alias_method_chain方法在3.1以后的替代使用方式
alias_method_chain()
是rails里的一个广泛使用的方法,简单说,就是你要重写一个方法,在里面加上一个新方法后,还要使用同名的原方法调用。
使用和实现如下,
Ruby代码- 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
- 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
复制代码 再看一个
Ruby代码- 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
- d
- 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
复制代码 就说这个事现在流行的方式怎么调:
Ruby代码- 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 PreExtension
- end
-
- s = Something.new
- s.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
- 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 PreExtension
- end
- s = Something.new
- s.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有个顺序覆盖
Ruby代码
- module PreExtension; end
- module PostExtension; end
-
- include PreExtension
- include PostExtension
- end
-
- Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
- module PreExtension; end
- module PostExtension; end
- include PreExtension
- include PostExtension
- end
- Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
复制代码 Ruby代码- class SomethingNew
- module Base
- def my_method
- puts "(A)"
- end
- end
-
- module Extension
- def my_method
- puts "(B)"
- super
- end
- end
-
- include Base
- include Extension
- end
-
- SomethingNew.new.my_method
- # Output:
- # >> (B)
- # >> (A)
-
- SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
复制代码 |