问题描述
我尝试通读各种博客文章,试图解释 alias_method_chain 以及使用和不使用它的原因.我特别注意:
I've tried reading through various blog posts that attempt to explain alias_method_chain and the reasons to use it and not use it. In particular, I took heed to:
http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain
和
http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/
我仍然没有看到 alias_method_chain 的任何实际用途.谁能解释一下.
I still do not see any practical use for alias_method_chain. Would anyone be able to explain a few things.
1 - 它还在使用吗?
2 - 你什么时候会使用 alias_method_chain 以及为什么?
1 - is it still used at all?
2 - when would you use alias_method_chain and why?
推荐答案
显然是的,alias_method_chain()
是 仍在 Rails 中使用(从 3.0.0 版开始).
Apparently yes, alias_method_chain()
is still used in Rails (as of version 3.0.0).
2 - 你什么时候使用alias_method_chain 以及为什么?
(注意:以下主要基于,这是一本您应该亲自动手的好书.)
(Note: the following is largely based on the discussion of alias_method_chain()
in Metaprogramming Ruby by Paolo Perrotta, which is an excellent book that you should get your hands on.)
让我们从一个基本的例子开始:
Let's start with a basic example:
class Klass
def salute
puts "Aloha!"
end
end
Klass.new.salute # => Aloha!
现在假设我们想用日志记录行为包围 Klass#salute()
.我们可以做到 Perrotta 所说的周围别名:
Now suppose that we want to surround Klass#salute()
with logging behavior. We can do that what Perrotta calls an around alias:
class Klass
def salute_with_log
puts "Calling method..."
salute_without_log
puts "...Method called"
end
alias_method :salute_without_log, :salute
alias_method :salute, :salute_with_log
end
Klass.new.salute
# Prints the following:
# Calling method...
# Aloha!
# ...Method called
我们定义了一个名为 salute_with_log()
的新方法,并将其别名为 salute()
.用于调用 salute()
的代码仍然有效,但它也获得了新的日志记录行为.我们还为原来的 salute()
定义了一个别名,所以我们仍然可以不记录就行礼:
We defined a new method called salute_with_log()
and aliased it to salute()
. The code that used to call salute()
still works, but it gets the new logging behavior as well. We also defined an alias to the original salute()
, so we can still salute without logging:
Klass.new.salute_without_log # => Aloha!
所以,salute()
现在被称为 salute_without_log()
.如果我们想记录日志,我们可以调用 salute_with_log()
或 salute()
,它们是相同方法的别名.使困惑?不错!
So, salute()
is now called salute_without_log()
. If we want logging, we can call either salute_with_log()
or salute()
, which are aliases of the same method. Confused? Good!
据 Perrotta 所说,这种环绕别名在 Rails 中很常见:
According to Perrotta, this kind of around alias is very common in Rails:
再看 Rails 的另一个例子用自己的方式解决问题.一些版本之前,Rails 代码包含同一个习语的许多实例:Around Alias (155) 用于添加一个功能到方法,而旧的该方法的版本被重命名为就像是method_without_feature()
.除了方法名称,每改变一次时间,这样做的代码是总是一样的,到处都是重复的这个地方.在大多数语言中,您无法避免这种重复.在 Ruby 中,你可以撒一些元编程魔法对你的模式并将其提取到自己的方法……就这样诞生了alias_method_chain()
.
换句话说,您提供原始方法 foo()
和增强方法 foo_with_feature()
,最终得到三个方法: foo()
、foo_with_feature()
和 foo_without_feature()
.前两个包括该功能,而第三个没有.而不是复制这些别名,alias_method_chain()
由 ActiveSupport 提供 为您完成所有别名操作.
In other words, you provide the original method, foo()
, and the enhanced method, foo_with_feature()
, and you end up with three methods: foo()
, foo_with_feature()
, and foo_without_feature()
. The first two include the feature, while the third doesn't. Instead of duplicating these aliases all around, alias_method_chain()
provided by ActiveSupport does all the aliasing for you.
这篇关于Ruby on Rails:alias_method_chain,它到底是做什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!