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

obj的metaclass和class的metaclass有什么区别

浏览 4434 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-26  
最近在看r4r,有个概念比较糊涂了。
就是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的时候再深入了解

以上问题就再没有相关论述了,而这些也是我想了解的,有没有可以推荐的文章可以阅读?
   发表时间: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

0 请登录后投票
   发表时间:2007-01-26  
ruby的类体系及其实现机制比较抽象,需要用抽象的眼光去看待.
实际上它的那个类机制的实现图一眼看上去,仿佛是一个封闭的"八卦图",从起点回到终点,是很奇妙的事情。再说下去就扯到哲学上去了,呵呵。。。

上面提到的"singleton class",近期有人提出用"eigenclass"来表达更好,这是有理由的:

eigen意思是"自己的",eigenclass意思就是只属于"自己的类".你想象一下:

你,我,他,我们都是活生生的人,是人就有人的"共性",例如七情六欲,生老病死之类的特征,但是你我他,我们彼此之间之所以能够相互区别,那是因为还有一些东西是你我他所特有的,只属于"自己"的特征.你我他,我们每个人无论怎么成长变化,除了具有人类的一般特征外,我们还是能够始终把自己当成自己,不会出现"我忽然变成了你,你忽然成为了他"这样的事情。这就是所谓的人的"个性"及其隐藏在背后的"eigenclass".

所以,每个人都是人,同时每个人都有属于他自己的eigenclass.
“认识你自己”是古代哲人的一个劝解,或许就是让我们能够找到自己的eigenclass吧,哈哈
而ruby的作者matz说“跟从你的心”,这里的"心"或许就是属于你自己的eigenclass吧,不知道对不对?
0 请登录后投票
   发表时间:2007-01-26  
eigenclass这个问题是我在接触ruby语言之前就思考过的问题,那个时候我还在PHP阵营里,期望在PHP里找到答案。但PHP语言没有提供类似这样的比较好的支持
直到我遇上了ruby语言,发现ruby语言实现了它,所以我的欣喜之情是不言而喻的.
下面是我在喜悦国际村的讨论:
http://www.phpx.com/happy/thread-113244-1-2.html
该问题在ruby语言里得到了让我满意的解决,嘿嘿。
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间: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和它又是什么关系呢?

0 请登录后投票
   发表时间: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这个类对象
0 请登录后投票
   发表时间:2007-01-26  
明白了,谢谢,这样的答复就比较确定了。
另外推荐一篇文章
http://www.whytheluckystiff.net/articles/seeingMetaclassesClearly.html
也是关于singleton class不错的文章
0 请登录后投票
   发表时间:2007-01-27  
fredzhang 写道
明白了,谢谢,这样的答复就比较确定了。
另外推荐一篇文章
http://www.whytheluckystiff.net/articles/seeingMetaclassesClearly.html
也是关于singleton class不错的文章

thanks
0 请登录后投票
   发表时间: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增加方法和直接给这个类增加方法是一样的效果
0 请登录后投票
论坛首页 编程语言技术版

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