alias_method_chain()是rails里的一个广泛使用的方法,简单说,就是你要重写一个方法,在里面加上一个新方法后,还要使用同名的原方法调用。使用和实现如下,
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_logendKlass.new.salute# Prints the following:# Calling method...# Aloha!# ...Method called
再看一个
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 endend
就说这个事现在流行的方式怎么调:
class Something module Base def my_method # (A) original functionality end end module PreExtension def my_method # (B) before the original super # calls whatever was my_method before this definition was made end end module PostExtension def my_method super # calls whatever was my_method before this definition was made # (C) after the original end end include Base # this is needed to place the base methods in the inheritance stack include PreExtension # this will override the original my_method include PostExtension # this will override my_method defined in PreExtensionends = Something.news.my_method #=> this is a twice extended method call that will execute code in this order:#=> (B) before the original#=> (A) the original#=> (C) after the original
super是上一个module里同名方法include有个顺序覆盖
module PreExtension; end module PostExtension; end include PreExtension include PostExtensionendSomething.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
class SomethingNew module Base def my_method puts "(A)" end end module Extension def my_method puts "(B)" super end end include Base include ExtensionendSomethingNew.new.my_method# Output:# >> (B)# >> (A)SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
贪婪是最真实的贫穷,满足是最真实的财富