alias_method_chain方法在3.1以后的替代使用方式
alias_method_chain()
是rails里的一个广泛使用的方法,简单说,就是你要重写一个方法,在里面加上一个新方法后,还要使用同名的原方法调用。
使用和实现如下,
Ruby代码- 1.class Klass
- 2. def salute_with_log
- 3. puts "Calling method..."
- 4. salute_without_log
- 5. puts "...Method called"
- 6. end
- 7.
- 8. alias_method :salute_without_log, :salute
- 9. alias_method :salute, :salute_with_log
- 10.end
- 11.
- 12.Klass.new.salute
- 13.# Prints the following:
- 14.# Calling method...
- 15.# Aloha!
- 16.# ...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代码- 1.module InstanceMethods
- 2. def deliver_with_switchable_smtp!(mail = @mail)
- 3. unless logger.nil?
- 4. logger.info "Switching SMTP server to: #{custom_smtp.inspect}"
- 5. end
- 6. ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil?
- 7. deliver_without_switchable_smtp!(mail = @mail)
- 8. end
- 9.end
- 10.def self.included(receiver)
- 11. receiver.send :include, InstanceMethods
- 12. receiver.class_eval do
- 13. alias_method_chain :deliver!, :switchable_smtp
- 14. end
- 15.end
- 16.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代码- 1.class Something
- 2. module Base
- 3. def my_method
- 4. # (A) original functionality
- 5. end
- 6. end
- 7.
- 8. module PreExtension
- 9. def my_method
- 10. # (B) before the original
- 11. super # calls whatever was my_method before this definition was made
- 12. end
- 13. end
- 14.
- 15. module PostExtension
- 16. def my_method
- 17. super # calls whatever was my_method before this definition was made
- 18. # (C) after the original
- 19. end
- 20. end
- 21.
- 22. include Base # this is needed to place the base methods in the inheritance stack
- 23. include PreExtension # this will override the original my_method
- 24. include PostExtension # this will override my_method defined in PreExtension
- 25.end
- 26.
- 27.s = Something.new
- 28.s.my_method
- 29.#=> this is a twice extended method call that will execute code in this order:
- 30.#=> (B) before the original
- 31.#=> (A) the original
- 32.#=> (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代码- 1.
- 2. module PreExtension; end
- 3. module PostExtension; end
- 4.
- 5. include PreExtension
- 6. include PostExtension
- 7.end
- 8.
- 9.Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
- module PreExtension; end
- module PostExtension; end
- include PreExtension
- include PostExtension
- end
复制代码 Something.ancestors # => [Something, Something: ostExtension, Something: reExtension, Object, Kernel]
Ruby代码- 1.class SomethingNew
- 2. module Base
- 3. def my_method
- 4. puts "(A)"
- 5. end
- 6. end
- 7.
- 8. module Extension
- 9. def my_method
- 10. puts "(B)"
- 11. super
- 12. end
- 13. end
- 14.
- 15. include Base
- 16. include Extension
- 17.end
- 18.
- 19.SomethingNew.new.my_method
- 20.# Output:
- 21.# >> (B)
- 22.# >> (A)
- 23.
- 24.SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
复制代码 |