alias_method_chain方法在3.1以后的替代使用方式

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]

贪婪是最真实的贫穷,满足是最真实的财富

alias_method_chain方法在3.1以后的替代使用方式

相关文章:

你感兴趣的文章:

标签云: