锁定老帖子 主题:Ruby 单件类
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-05-14
下面是Ruby 1.8.4的代码行数(其它版本可能会有所不同)
893 rb_define_singleton_method(obj, name, func, argc) 894 VALUE obj; 895 const char *name; 896 VALUE (*func)(); 897 int argc; 898 { 899 rb_define_method(rb_singleton_class(obj), name, func, argc); 900 } (class.c) 这个方法为一个对象obj创建一个singleton method 857 rb_singleton_class(obj) ...... 873 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && 874 rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { 875 klass = RBASIC(obj)->klass; 876 } 877 else { 878 klass = rb_make_metaclass(obj, RBASIC(obj)->klass); 879 } (class.c) 请注意873行的判断,如果这个对象的klass所指向的已经是一个Singleton Class,并且它的实例变量里面__attached__指向当前这个对象的话,表示它已经是这个对象的singleton class,不然的话,就创建(878),但其实这个rb_make_metaclass名字取得不好,估计matz当时是为了类取的名字,最后在这个rb_make_metaclass的中间: 157 rb_singleton_class_attached(klass, obj); 这里的klass就是新创建的那个singleton class,obj就是正在被创建singleton class的obj,而 rb_singleton_class_attached的目的就是把它的对象放在它的实例变量表里面 138 void 139 rb_singleton_class_attached(klass, obj) ..... 146 st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj); .... _attached__ 没有 @ 这样的前缀,但是由于它保存在实例变量表中,因此它还是一个实例变量。这样一个实例变量永远不可能在Ruby层次读到,因此它可以用来保存系统专用的数据。 现在让我们来思考一下klass和obj之间的关系。klass是obj的单件类。也就是说,这个“不可见”的实例变量允许单件类记住创建它的对象实例。单件类发生变化的时候需要使用这个值,最主要是调用实例(obj)上的hook方法。例如,当一个方法增加到一个单件类时,obj的singleton_method_added方法被调用。没有逻辑上的必要性一定要这样做,但语言本身就是这样定义的。 |
|
返回顶楼 | |
发表时间:2006-05-14
为什么一定是java代码,其它语言的代码怎么搞?
|
|
返回顶楼 | |
发表时间:2006-05-14
potian 写道 为什么一定是java代码,其它语言的代码怎么搞?
...[/code\] |
|
返回顶楼 | |
发表时间:2006-05-14
robbin 写道 potian 写道 为什么一定是java代码,其它语言的代码怎么搞?
...[/code\] 谢了*2 改了以后看起来好多了 |
|
返回顶楼 | |
发表时间:2006-05-14
引用 但其实这个rb_make_metaclass名字取得不好,估计matz当时是为了类取的名字
引用 但对于类对象是不一样的,它们一被创建的时候就有了singleton class,准确地说是metaclass
一篇题为Seeing Metaclasses Clearly的文章,他把这种情形下的Singleton class都称作了metaclass,不论是针对Object实例还是Class实例(Classes Are Objects,too)。这样就能解释得通为什么起名叫rb_make_metaclass了。 祝福RubyUnderRails |
|
返回顶楼 | |
发表时间:2006-05-19
我最近正在把Javaeye的帖子作个整理,集中放在 rubytao.com ,大家有兴趣可以去看看
最近:一个新的小例子,实现一个简单的DSL语言 一个小小的计划:http://www.rubytao.com/blogs 有意见者可以在Javaeye上一起讨论 也欢迎各位提供自己的心得 |
|
返回顶楼 | |
发表时间:2006-06-06
刚拜读了potian在rubytao.com关于metaclass的文章,豁然开朗,十分期待"Module的mixin" 这篇文章,有点吊胃口哦~
还是静候后续吧,有深度俺喜欢 |
|
返回顶楼 | |
发表时间:2006-10-12
读完后才明白什么事单件类和单件方法,谢谢!
|
|
返回顶楼 | |
发表时间:2007-08-28
programming ruby上面写得那么清楚,图表实例一目了然
为什么说读不懂呢 有点搞笑吧 Module的mixin就是生成一个代理类作为类的直接超类,代理类代理到module 同样obj.extend也是为该对象生成一个代理类作为直接超类,代理类代理到module 所以在类中使用extend module的话,那个module的方法会自动成为类的类方法 |
|
返回顶楼 | |
发表时间:2007-08-29
programming ruby上有一节花了大量篇幅专门介绍ruby的这个特性,我始终看的不是很透彻,特别是potian所说的单件类(class<<obj)。不及potian的这个帖子来的透彻。
另,这里所谓的单件类,容易和design pattern中的单例模式像混淆,我还是建议叫metaclass。 |
|
返回顶楼 | |