Delegate是一种应用composite来代替extend的机制,可以有效地降低代码的耦合性。

Rails 2.2增加了delegate方法,可以十分方便地实现delegate机制。

01.def delegate(*methods)
02. options = methods.pop
03. unless options.is_a?(Hash) && to = options[:to]
04. raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
05. end
06.
07. if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/8. raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."9. end
10.
11. prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
12.
13. methods.each do |method|
14. module_eval(<<-EOS, "(__DELEGATION__)", 1)
15. def #{prefix}#{method}(*args, &block)
16. #{to}.__send__(#{method.inspect}, *args, &block)
17. end
18. EOS
19. end
20.end

delegate方法首先检查传入的参数,正确参数形式为:method1, :method2, ..., :methodN, :to => klass[, :prefix => prefix]

delegate要求参数的最后必须是一个Hash,:to表示需要代理的类,:prefix表示代理的方法是否要加前缀,如果:prefix => true,则代理的方法名为klass_method1,

klass_method2, ..., klass_methodN,如果:prefix => prefix (prefix为string),则代理的方法名为prefix_method1, prefix_method2, ..., prefix_methodN。

最终通过module_eval动态生成每个方法定义。通过__send__方法调用:to类的方法。

来看看调用的例子:

简单的调用:

01.class Greeter < ActiveRecord::Base
02. def hello() "hello" end
03. def goodbye() "goodbye" end
04.end
05.
06.class Foo < ActiveRecord::Base
07. delegate :hello, :goodbye, :to => :greeter
08.end
09.
10.Foo.new.hello # => "hello"
11.Foo.new.goodbye # => "goodbye"

增加:prefix => true:

1.class Foo < ActiveRecord::Base
2. delegate :hello, :goodbye, :to => :greeter, :prefix => true
3.end
4.
5.Foo.new.greeter_hello # => "hello"
6.Foo.new.greeter_goodbye # => "goodbye"

自定义前缀名:

1.class Foo < ActiveRecord::Base
2. delegate :hello, :goodbye, :to => :greeter, :prefix => :foo
3.end
4.
5.Foo.new.foo_hello # => "hello"
6.Foo.new.foo_goodbye # => "goodbye"

ruby的动态性再一次发挥了强大的功能!

转自:http://www.cnblogs.com/orez88/articles/1717438.html

rails delegate机制的更多相关文章

  1. iOS消息传递机制

    每个应用或多或少都由一些需要相互传递消息的对象结合起来以完成任务.在这篇文章里,我们将介绍所有可用的消息传递机制,并通过例子来介绍怎样在苹果的框架里使用.我们还会选择一些最佳范例来介绍什么时候该用什么 ...

  2. IOS OS X 中集中消息的传递机制

    1 KVO (key-value Observing) 是提供对象属性被改变是的通知机制.KVO的实现实在Foundation中,很多基于 Foundation 的框架都依赖与它.如果只对某一个对象的 ...

  3. IOS开发之delegate和Notification的区别

    delegate针对one-to-one关系,并且reciever可以返回值给sender: notification 可以针对one-to-one/many/none,reciever无法返回值给s ...

  4. Gradle 用法总结

    用过android studio的对gradle应该都不陌生了,gradle文件的基本配置大同小异,略做了解使用应该是没什么问题了.但是深入细致的了解一下对于理解项目还是很有帮助的,尤其是遇到一些配置 ...

  5. Android Gradle 经验总结

    用过android studio的对gradle应该都不陌生了,gradle文件的基本配置大同小异,略做了解使用应该是没什么问题了.但是深入细致的了解一下对于理解项目还是很有帮助的,尤其是遇到一些配置 ...

  6. [Tomcat] Tomcat的classloader

    定义 同其他服务器应用一样,tomcat安装了各种classloader(classes that implement java.lang.ClassLoader) Bootstrap | Syste ...

  7. 如何给开源的DUILib支持Accessibility

    最近的工作是给开源的DUILib支持Accessibility, 一些经验记录并分享下. 微软的Accessibility其实Windows平台上一个挺重要的东西, 尽管在国内不受重视,但是如果你的软 ...

  8. 李洪强iOS经典面试题135-Objective-C

    可能碰到的iOS笔试面试题(5)--Objective-C 面试笔试都是必考语法知识的.请认真复习和深入研究OC. Objective-C 方法和选择器有何不同?(Difference between ...

  9. Gradle学习系列之三——读懂Gradle语法

    在本系列的上篇文章中,我们讲到了创建Task的多种方法,在本篇文章中,我们将学习如何读懂Gradle. 请通过以下方式下载本系列文章的Github示例代码: git clone https://git ...

随机推荐

  1. 【 LVS 】类型及算法

    一.概念: LVS( linux virtual server ) : Linux虚拟服务器 lvs是一个负载均衡设备,它不提供任何服务,用户请求到这里的时候,它将客户需求转发至后端的realserv ...

  2. Android 曲线动画animation,类似加入购物车动画

    按照惯例先放效果图:图中小球做抛物线运动 资源图片 1.首先布局文件activity_main.xml,布局很简单,就一个测试按钮 <RelativeLayout xmlns:android=& ...

  3. java javac 的区别

    cmd中,执行java命令与javac命令的区别: javac:是编译命令,将java源文件编译成.class字节码文件. 例如:javac hello.java 将生成hello.class文件 j ...

  4. postman用法总结+newman持续集成

    一.postman 1.GET 请求:点击Params,输入参数及value,可输入多个显示在URL链接上(GET请求的请求头与请求参数如在接口文档中无特别声明时可以不填) 2.POST请求:在bod ...

  5. 获取apk的appPackage和appActivity方法

    aapt dump badging +客户端包所在路径+客户端包名称;      aapt是SDK\tools侠的工具: adb shell          logcat | grep cmp= 将 ...

  6. 二维树状数组+差分【p4514】上帝造题的七分钟

    Description "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n\times m\)矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为\((a,b)\),右 ...

  7. luogu P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...

  8. [BZOJ5020][THUWC2017]在美妙的数学王国中畅游(LCT)

    5020: [THUWC 2017]在美妙的数学王国中畅游 Time Limit: 80 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 323  ...

  9. CodeForces - 981E Addition on Segments

    考虑每个点i在什么情况下会成为最大值. 当选的区间子集是 包含i的区间的一个子集的时候,i肯定会是最大值. 所以我们就可以用这种方法得到所有点的可能的最大值是多少... 也就是说,最后的局面可以仅由一 ...

  10. [CF911B]Two Cakes

    题目大意: 有两种蛋糕,分别被切成了a块和b块,要把这些蛋糕分到n个盘子里. 要求每个盘子里只能有一种蛋糕,每一种蛋糕都被分.问最优情况下,盘子里至少能放几个蛋糕. 思路: 二分答案. 由于每个蛋糕都 ...