alias_method_chain方法在3.1以后的替代使用方式
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 originalsuper是上一个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 # =>
module PreExtension; end
module PostExtension; end
include PreExtension
include PostExtension
endSomething.ancestors # =>
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 # => 谢谢分享 屯哥的这不错。
页:
[1]