赞 | 2 |
VIP | 143 |
好人卡 | 1 |
积分 | 1 |
经验 | 216792 |
最后登录 | 2019-10-10 |
在线时间 | 24 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 61
- 在线时间
- 24 小时
- 注册时间
- 2008-8-5
- 帖子
- 1924
|
本帖最后由 紫苏 于 2010-10-3 09:23 编辑
这个的确是设计模式的的问题。以前 6R 就有高手提出过,根据 UI 设计原理,我们应该把这些命令当做按钮控件,触发按钮时调用与控件相关联的回调函数,和六祈这里使用的思想不谋而合,只不过该高手用的是 Proc。
关于绑定,Method 对象在创建时会创建对象分配内存并绑定到其拥有者对象,send 的话少了这些过程,因为它触发的是本身就存在于对象虚表中的成员。
一个简单的测试:- def foo
- end
- CASES = 1000000
- t = Time.now
- CASES.times {
- send :foo
- }
- p Time.now - t
- t = Time.now
- CASES.times {
- method(:foo).call
- }
- p Time.now - t
复制代码 刚才翻 Programming Ruby 1.9 才发现一个新东西,而这个东西也存在于 Ruby 1.8 中,但在老版的 Programming Ruby 里根本没提到:
Ruby supports two forms of objectified methods. Class Method is used to represent methods that are associated with a particular object: these method objects are bound to that object. Bound method objects for an object can be created using Object#method. Ruby also supports unbound methods, which are method objects that are not associated with a particular object. These can be created either by calling unbind on a bound method object or by calling Module#instance_method. Unbound methods can be called only after they are bound to an object. That object must be a kind_of? the method’s original class.
所以有时也可以使用 UnboundMethod 来最大化灵活性(可以随随意绑定到任何对象),同时也保证了不因为绑定而降低性能。
Ruby中不会发生,也不存在function.fun这种调用方式,只有对象才可以接收消息,而def的方法显然还不是一个对象
这个其实要做到也可以的,只不过会让读者觉得很困惑。Ruby 的一切动态绑定都和上下文有关,只要接受者的上下文能够响应请求的符号,就能调用到预期的方法:- def foo
- public
- def bar
- p self
- end
- end
- foo.bar
复制代码 为什么这里可以这样用?因为 foo 是在顶层定义的,所以 foo 内是 Object(XP 中是 NilClass,VX 和标准 Ruby 解释器下都是 Object)的实例上下文,在实例上下文里定义的 bar 方法自然也绑定到了这里,也就成了 Object 的实例方法。于是首先调用 foo 后,返回一个 nil(因为 foo 没有返回值),nil 是 Object 类型,所以这里就成功地响应了 Object#bar。之所以有那个 public,是因为用户在顶层中定义的方法加入到 Object 中后,其访问权限被设为了公有(public),然而在纯 Ruby 中,加入到 Object 后其访问权限应该是私有的(private)。具体可以参考:http://szsu.wordpress.com/2009/11/07/top_level_object_kernel/
换一个例子来看:- class Klass
- def foo
- def bar
- p self
- end
- end
- end
- Klass.new.foo.bar # error
复制代码 就不行了。因为 Klass.new.foo 返回的还是 nil,而 nil 却不是 Klass 类型,所以无法响应 Klass 的实例方法 bar。其它类型的上下文也是一个道理。如果让 bar 返回 self 就行了:- class Klass
- def foo
- def bar
- p self
- end
- self
- end
- end
- Klass.new.foo.bar # OK
复制代码 |
评分
-
查看全部评分
|