1 - 它还在被使用吗?
显然是的,alias_method_chain()
在 Rails 中 仍然被使用(截至版本 3.0.0)。
2 - 何时使用alias_method_chain以及为什么使用它?
(注意:以下内容主要基于 Paolo Perrotta 的《Ruby元编程》中关于alias_method_chain()
的讨论,这是一本非常好的书籍,你应该去阅读一下。)
让我们从一个基本示例开始:
class Klass
def salute
puts "Aloha!"
end
end
Klass.new.salute
现在假设我们想要在
Klass#salute()
周围添加日志记录行为。我们可以使用Perrotta所称的
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
我们定义了一个名为
salute_with_log()
的新方法,并将其重命名为
salute()
。以前调用
salute()
的代码仍然有效,但它也获得了新的日志记录行为。我们还定义了一个原始
salute()
的别名,因此我们仍然可以进行无需记录日志的问候:
Klass.new.salute_without_log
因此,salute()
现在被称为salute_without_log()
。如果我们想要记录日志,可以调用salute_with_log()
或salute()
,它们是同一方法的别名。感到困惑?很好!
根据Perrotta的说法,这种around alias在Rails中非常常见:
看另一个Rails解决问题的例子。几个版本之前,Rails代码包含许多相同的习惯用语:使用Around Alias(155)添加功能到方法中,并将旧版本的方法重命名为类似于method_without_feature()
的名称。除了每次更改的方法名称之外,执行此操作的代码始终相同,复制到各个地方。在大多数语言中,您无法避免这种重复。在Ruby中,您可以在模式上撒些元编程魔法,并将其提取到自己的方法中...于是诞生了alias_method_chain()
。
换句话说,您提供原始方法
foo()
和增强方法
foo_with_feature()
,最终得到三种方法:
foo()
、
foo_with_feature()
和
foo_without_feature()
。前两个包含该特性,而第三个不包含该特性。为了避免重复使用这些别名,
ActiveSupport提供的alias_method_chain()
会为您处理所有别名。
alias_method_chain :foo, :feature
,我们就会得到3个方法:foo
,foo_with_feature
,foo_without_feature
,正如Yases Sulaiman之前所描述的那样,这些方法已经被正确地命名别名了。 - freemanoid