浏览 4433 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-01-26
就是Class也是对象,那么对于普通object来说,它的kclass指向该object的单件类既metaclass,然而对于该object的class: obj.class 来说,由于它也是对象,因此它也存在自己单件类,它的kclass指向类对象的单件类metaclass,那么这两个metaclass应当是一个吗? 这个问题在potian的MetaClass – 类对象的单件类这篇文章中应当有阐述,但是rubytao网站已经无法访问了,从google的cache中无法看到原文所附带的图,所以对以上问题比较困惑。 此外: potian还提到: 虽然我们已经成功地解释了为什么Object.class是Class,但是如何表达Class也是一个对象(因为Ruby中任何数据都是对象)?Class按规则也具有它的meta-class—(Class),那么我们如何表达Class本身也是Class? 这些问题将在后面需要掌握Module的mixin的时候再深入了解 以上问题就再没有相关论述了,而这些也是我想了解的,有没有可以推荐的文章可以阅读? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-01-26
metaclass是不准确的说法,用"singleton class"来表示才准确,近期有人提议用"eigenclass"来表达更好。
下面我沿用ruby原来的"singleton class"来描述(实际上我认为eigenclass这个术语更好一些) Person=Class.new #上面的定义和下面用class关键字的定义是等价的 #class Person #end axgle=Person.new clark=Person.new def clark.fly puts "I can fly,anyother?" end clark.fly puts clark.class #axgle.fly def Person.getTotal puts "How many people on earth?" end Person.getTotal =begin clark和axgle一样,都是人,但是有一点不同,那就是clark会飞,实际上clark就是传说中的"超人"(Superman)! 超人也是人,但是属于比较“另类”的人。所以实际上超人是人类的一个子类,在这里只有clark是超人。 这里的"超人"类就是clark这个普通对象的"singleton class" 而要是你问:clark.class是什么,那么答案是Person,"singleton class"是匿名的,如同clark一眼看上去,你不知道他是超人类似. 下面再接着说Person类这个"对象",与上面的分析是类似的: Person这个类是对象,这个对象也有"singleton class"。因为Person只不过是Class这个类的实例,Class还可以有其他实例,例如String什么的。 如果你定义一个方法,只让Person调用,不让String类调用,例如Person.getTotal,那么这个Person的类方法就定义在了Person这个对象的"singleton class"中。 同样,Person的"singleton class"依然是匿名的,并且是Class这个类的子类。 由此可见,普通对象的"singleton class"是该普通对象的类的"匿名子类";类的"singleton class"是该类的类(即Class)的"匿名子类"。 一句话,"singleton class"就是对象(无论是普通对象,还是类本身)特有的方法的归属地,该归属地是该对象原来所在的类的子类。 希望这个解释能够让理解比较清晰。 =end |
|
返回顶楼 | |
发表时间:2007-01-26
ruby的类体系及其实现机制比较抽象,需要用抽象的眼光去看待.
实际上它的那个类机制的实现图一眼看上去,仿佛是一个封闭的"八卦图",从起点回到终点,是很奇妙的事情。再说下去就扯到哲学上去了,呵呵。。。 上面提到的"singleton class",近期有人提出用"eigenclass"来表达更好,这是有理由的: eigen意思是"自己的",eigenclass意思就是只属于"自己的类".你想象一下: 你,我,他,我们都是活生生的人,是人就有人的"共性",例如七情六欲,生老病死之类的特征,但是你我他,我们彼此之间之所以能够相互区别,那是因为还有一些东西是你我他所特有的,只属于"自己"的特征.你我他,我们每个人无论怎么成长变化,除了具有人类的一般特征外,我们还是能够始终把自己当成自己,不会出现"我忽然变成了你,你忽然成为了他"这样的事情。这就是所谓的人的"个性"及其隐藏在背后的"eigenclass". 所以,每个人都是人,同时每个人都有属于他自己的eigenclass. “认识你自己”是古代哲人的一个劝解,或许就是让我们能够找到自己的eigenclass吧,哈哈 而ruby的作者matz说“跟从你的心”,这里的"心"或许就是属于你自己的eigenclass吧,不知道对不对? |
|
返回顶楼 | |
发表时间:2007-01-26
eigenclass这个问题是我在接触ruby语言之前就思考过的问题,那个时候我还在PHP阵营里,期望在PHP里找到答案。但PHP语言没有提供类似这样的比较好的支持
直到我遇上了ruby语言,发现ruby语言实现了它,所以我的欣喜之情是不言而喻的. 下面是我在喜悦国际村的讨论: http://www.phpx.com/happy/thread-113244-1-2.html 该问题在ruby语言里得到了让我满意的解决,嘿嘿。 |
|
返回顶楼 | |
发表时间:2007-01-26
另外,既然一个对象的eigenclass是这个对象的类的子类,那么eigenclass里定义的方法就可以“继续使用”这个对象的类里的实例方法。这是一个符合人的直觉的特性,例如:
class Person def eat puts "eating..." end end clark=Person.new def clark.fly_and_eat puts "flying..." puts "and" self.eat end clark.fly_and_eat |
|
返回顶楼 | |
发表时间:2007-01-26
谢谢你的详细回答,不过跟我想了解的还有一些差异
axgle 写道 而要是你问:clark.class是什么,那么答案是Person,"singleton class"是匿名的,如同clark一眼看上去,你不知道他是超人类似. 我所想问的是,这个clark的singleton class,和Person的singleton class 是同一个singleton class? Person是clark的singleton class的超类,但Person自己的singleton class和它又是什么关系呢? |
|
返回顶楼 | |
发表时间:2007-01-26
fredzhang 写道 谢谢你的详细回答,不过跟我想了解的还有一些差异
axgle 写道 而要是你问:clark.class是什么,那么答案是Person,"singleton class"是匿名的,如同clark一眼看上去,你不知道他是超人类似. 我所想问的是,这个clark的singleton class,和Person的singleton class 是同一个singleton class? Person是clark的singleton class的超类,但Person自己的singleton class和它又是什么关系呢? clark的singleton class,和Person的singleton class 不是同一个singleton class clark是Person类的实例,Person是Class类的实例。 clark的singleton class里记录的是clark的singleton method,例如fly Person的singleton class里记录的是Person的singleton method,例如getTotal 这里的关键是大家都容易理解clark是个对象;而Person是个类,只要把Person这个类也看作是对象(即Class这个类的实例),那么就存在这个类的"singleton class" Person类的"singleton class"定义的方法,是Person这个类调用的方法,属于通常说的类方法. clark对象的"singleton class"定义的方法,是clark这个实例调用的方法,属于通常说的实例方法. 没有"singleton class"的时候:clark->Person->Class 意思是:clark是Person类的实例,Person类是Class类的实例 有"singleton class"后:clark->(clark)->Person->(Person)->Class (clark)表示clark的"singleton class",(Person)表示Person类的"singleton class". 意思是:clark是(clark)这个singleton class的实例,(clark)继承Person类;Person是(Person)的实例,(Person)继承Class类 (clark)类里的方法只属于clark对象,同样(Person)类里的方法只属于Person这个类对象 |
|
返回顶楼 | |
发表时间:2007-01-26
明白了,谢谢,这样的答复就比较确定了。
另外推荐一篇文章 http://www.whytheluckystiff.net/articles/seeingMetaclassesClearly.html 也是关于singleton class不错的文章 |
|
返回顶楼 | |
发表时间:2007-01-27
fredzhang 写道 明白了,谢谢,这样的答复就比较确定了。
另外推荐一篇文章 http://www.whytheluckystiff.net/articles/seeingMetaclassesClearly.html 也是关于singleton class不错的文章 thanks |
|
返回顶楼 | |
发表时间:2007-01-27
看这篇
引用 此笔记是为了帮助理解 "<<" 指令
ruby语言允许我们在一个对象的基础上定义类,使得我们可以单独扩展一个对象的行为,例子如下 test="hello" #普通string normal=a.dup #还是普通string class << test def to_s "value is #{self}" end end #test对象已经被更新, normal保持不变 运行完上述代码以后 normal.to_s =="hello" test.to_s=="value is hello" 从这个例子上来看, 此时的test对象的类已经被扩展为新的to_s方法,但是这个扩展只能影响到test对象自己 ,其他的string对象还是原来的方法. 我的理解: 基于对象的类通过指令"<<" 来定义, 他能够扩展并且只能扩展被定义的对象, 同时不能影响系统中其他同类型的对象 "<<"指令可以用来临时修改一个对象,此外,这个指令还可以用来定义类的方法, 一般定义类方法是通过如下语法 class Test def Test.say "hello" end end 如果嫌需要写多次类名麻烦,可以通过self替换 class Test def self.say "hello" end end 有了"<<"指令,还可以这样来 class Test class << self def say "hello" end end end 上述三者的定义是等价的,而且在ruby源代码中很容易看到第三种用法 解释: 在ruby中,每一个类都有一个唯一实例的metaclass. 类定义的方法都存在这个metaclass中 通过"<<"对这个唯一实例的metaclass作扩展,给metaclass增加方法和直接给这个类增加方法是一样的效果 |
|
返回顶楼 | |