ran*_*its 51 ruby ruby-on-rails
我已经尝试阅读各种博客文章,试图解释alias_method_chain以及使用它的原因而不是使用它.特别是,我注意到:
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的任何实际用途.任何人都可以解释一些事情.
1 - 它还在使用吗?
2 - 你何时会使用alias_method_chain?为什么?
Yas*_*man 104
1 - 它还在使用吗?
显然,是的,alias_method_chain()是Rails中仍在使用(如3.0.0版).
2 - 你何时会使用alias_method_chain?为什么?
(注意:以下内容主要基于Paolo Perrotta alias_method_chain()在Metaprogramming Ruby中的讨论,这是一本非常好的书,你应该亲自动手.)
让我们从一个基本的例子开始:
class Klass
def salute
puts "Aloha!"
end
end
Klass.new.salute # => Aloha!
Run Code Online (Sandbox Code Playgroud)
现在假设我们想要围绕Klass#salute()日志记录行为.我们可以做到Perrotta称之为别名的东西:
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
Run Code Online (Sandbox Code Playgroud)
我们定义了一个名为的新方法,salute_with_log()并将其别名化salute().以前调用的代码salute()仍可正常工作,但它也会获得新的日志记录行为.我们还定义了原始的别名salute(),所以我们仍然可以在没有记录的情况下致敬:
Klass.new.salute_without_log # => Aloha!
Run Code Online (Sandbox Code Playgroud)
所以,salute()现在被称为salute_without_log().如果我们想要记录,我们可以调用salute_with_log()或者salute(),它们是同一方法的别名.困惑?好!
根据Perrotta的说法,这种别名在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提供,为您完成所有别名.
alias_method_chain已经在Rails 5中被弃用了Module#prepend.
请求:https://github.com/rails/rails/pull/19434
更改日志:https://github.com/rails/rails/blob/b292b76c2dd0f04fb090d49b90716a0e6037b41a/guides/source/5_0_release_notes.md#deprecations-4
我不确定它是否在Rails 3中过时了,但是在此之前它仍然在版本中活跃使用。
您可以使用它在调用方法之前(或之后)注入一些功能,而无需修改调用该方法的任何位置。请参阅以下示例:
module SwitchableSmtp
module InstanceMethods
def deliver_with_switchable_smtp!(mail = @mail)
unless logger.nil?
logger.info "Switching SMTP server to: #{custom_smtp.inspect}"
end
ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil?
deliver_without_switchable_smtp!(mail = @mail)
end
end
def self.included(receiver)
receiver.send :include, InstanceMethods
receiver.class_eval do
alias_method_chain :deliver!, :switchable_smtp
end
end
end
Run Code Online (Sandbox Code Playgroud)
这是对ActionMailer的补充,允许在每次调用时换出SMTP设置deliver!。通过调用,alias_method_chain您可以定义一种用于 deliver_with_switchable_smtp!执行自定义内容的方法,并deliver_without_switchable_smtp!在完成后从此处进行调用。
alias_method_chain将旧名称别名为deliver!新的自定义方法,因此应用程序的其余部分甚至deliver!现在都不知道自定义内容。
| 归档时间: |
|
| 查看次数: |
18691 次 |
| 最近记录: |