免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2617 | 回复: 1
打印 上一主题 下一主题

alias_method_chain方法在3.1以后的替代使用方式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-04 13:22 |只看该作者 |倒序浏览
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  

  17. class Klass
  18.   def salute_with_log
  19.     puts "Calling method..."
  20.     salute_without_log
  21.     puts "...Method called"
  22.   end

  23.   alias_method :salute_without_log, :salute
  24.   alias_method :salute, :salute_with_log
  25. end

  26. Klass.new.salute
  27. # Prints the following:
  28. # Calling method...
  29. # Aloha!
  30. # ...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  

  17.   module InstanceMethods
  18.     def deliver_with_switchable_smtp!(mail = @mail)
  19.       unless logger.nil?
  20.         logger.info  "Switching SMTP server to: #{custom_smtp.inspect}"
  21.       end
  22.       ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil?
  23.       deliver_without_switchable_smtp!(mail = @mail)
  24.     end
  25.   end
  26.   def self.included(receiver)
  27.     receiver.send :include, InstanceMethods
  28.     receiver.class_eval do
  29.       alias_method_chain :deliver!, :switchable_smtp
  30.     end
  31.   end
  32. 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  

  33. class Something
  34.   module Base  
  35.     def my_method
  36.       # (A) original functionality
  37.     end
  38.   end

  39.   module PreExtension
  40.     def my_method
  41.       # (B) before the original
  42.       super # calls whatever was my_method before this definition was made
  43.     end
  44.   end

  45.   module PostExtension
  46.     def my_method
  47.       super # calls whatever was my_method before this definition was made
  48.       # (C) after the original
  49.     end
  50.   end

  51.   include Base # this is needed to place the base methods in the inheritance stack
  52.   include PreExtension # this will override the original my_method
  53.   include PostExtension # this will override my_method defined in PreExtension
  54. end

  55. s = Something.new
  56. s.my_method
  57. #=> this is a twice extended method call that will execute code in this order:
  58. #=> (B) before the original
  59. #=> (A) the original
  60. #=> (C) after the original
复制代码
super是上一个module里同名方法
include有个顺序覆盖
Ruby代码
  1.   module PreExtension; end  
  2.   module PostExtension; end  
  3.   
  4.   include PreExtension   
  5.   include PostExtension   
  6. end  
  7.   
  8. Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]  


  9.   module PreExtension; end
  10.   module PostExtension; end

  11.   include PreExtension
  12.   include PostExtension
  13. end

  14. Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, 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]  
复制代码

论坛徽章:
0
2 [报告]
发表于 2012-02-04 13:22 |只看该作者
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP