论坛首页 编程语言技术论坛

Ruby 单件类

浏览 22567 次
锁定老帖子 主题: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方法被调用。没有逻辑上的必要性一定要这样做,但语言本身就是这样定义的。
1 请登录后投票
   发表时间:2006-05-14  
为什么一定是java代码,其它语言的代码怎么搞?
0 请登录后投票
   发表时间:2006-05-14  
potian 写道
为什么一定是java代码,其它语言的代码怎么搞?


...[/code\]
0 请登录后投票
   发表时间:2006-05-14  
robbin 写道
potian 写道
为什么一定是java代码,其它语言的代码怎么搞?


...[/code\]


谢了*2

改了以后看起来好多了
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2006-05-19  
我最近正在把Javaeye的帖子作个整理,集中放在 rubytao.com ,大家有兴趣可以去看看

最近:一个新的小例子,实现一个简单的DSL语言

一个小小的计划:http://www.rubytao.com/blogs

有意见者可以在Javaeye上一起讨论

也欢迎各位提供自己的心得
0 请登录后投票
   发表时间:2006-06-06  
刚拜读了potian在rubytao.com关于metaclass的文章,豁然开朗,十分期待"Module的mixin" 这篇文章,有点吊胃口哦~

还是静候后续吧,有深度俺喜欢 
0 请登录后投票
   发表时间:2006-10-12  
读完后才明白什么事单件类和单件方法,谢谢!
0 请登录后投票
   发表时间:2007-08-28  
programming ruby上面写得那么清楚,图表实例一目了然

为什么说读不懂呢

有点搞笑吧

Module的mixin就是生成一个代理类作为类的直接超类,代理类代理到module

同样obj.extend也是为该对象生成一个代理类作为直接超类,代理类代理到module

所以在类中使用extend module的话,那个module的方法会自动成为类的类方法
0 请登录后投票
   发表时间:2007-08-29  
programming ruby上有一节花了大量篇幅专门介绍ruby的这个特性,我始终看的不是很透彻,特别是potian所说的单件类(class<<obj)。不及potian的这个帖子来的透彻。
另,这里所谓的单件类,容易和design pattern中的单例模式像混淆,我还是建议叫metaclass。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics