为什么 Ruby 中的所有东西都是类的实例?

5
我不太了解Ruby对象模型的一些事情。首先,Ruby中的所有东西都是Class的实例吗?以下所有语句都返回true:
p Object.instance_of?(Class)
p Class.instance_of?(Class)
p Module.instance_of?(Class)
p BasicObject.instance_of?(Class)
class Hello; end
p Hello.instance_of?(Class)

我不太理解这是怎么可能的,如果ObjectClass的超类,它怎么能同时作为Class的超类和实例呢(大多数Ruby对象模型上的图表都清楚地说明了这种层次结构)?这样就允许了一些疯狂的事情,比如:

p BasicObject.is_a?(Object) #=> true

这里使用的是Ruby 2.0版本,其中BasicObject.classClass,而Class.is_a?(Object)

3个回答

12
首先,Ruby中的一切都是Class的实例吗?
不是,不是所有的东西都是Class的实例。只有类才是Class的实例。
很多东西都不是Class的实例,例如字符串是String的实例,而不是Class的实例。数组是Array的实例,整数是Integer的实例,浮点数是Float的实例,trueTrueClass的实例,falseFalseClass的实例,nilNilClass的实例等等。
每个类都是Class的实例,就像每个字符串都是String的实例一样。
如果ObjectClass的超类,它如何既可以是Class的超类又可以是它自己的实例(大多数关于Ruby对象模型的图表明确说明了这种层次结构)?
这是魔法。
就像其他大多数语言一样,有一些核心实体被认为是简单存在的。它们从天而降,凭空出现,神奇地出现。
在Ruby中,其中一些神奇的东西是:
- Object没有超类,但是你无法定义没有超类的类,隐式直接超类总是Object。[注意:可能会有实现定义的Object的超类,但最终将有一个没有超类。] - ObjectClass的实例,它是Object的子类(这意味着间接地Object也是它自己的实例)。
  • ClassModule的子类,而Class本身则是一个Class实例。
  • Class也是一个Class实例。
  • 在Ruby中这些东西都无法被解释。

    BasicObjectObjectModuleClass必须同时存在,因为它们之间有循环依赖关系。

    虽然不能用Ruby代码表达这种关系,但这并不意味着Ruby语言规范不能规定它必须这样。由于Ruby实现对对象具有您作为程序员所没有的访问级别,因此需要实现者自己想办法解决。

    例如,Ruby实现可以先创建BasicObject,将其superclass指针和class指针都设置为null

    接下来,创建Object,将其superclass指针设置为BasicObject,将其class指针设置为null

    然后,创建Module,将其superclass指针设置为Object,将其class指针设置为null

    最后,创建Class,将其superclass指针设置为Module,将其class指针设置为null

    现在,我们可以覆盖BasicObjectObjectModuleClassclass指针,使它们都指向Class,这样就完成了。

    从系统外部来看,这很容易实现,但从内部看则会显得很奇怪。


    2

    请注意:

    p BasicObject.instance_of?(BasicObject) 
    

    输出结果为false

    也就是说,表达式BasicObject不是BasicObject的实例,它是另一个东西的实例,也就是一个Class对象,该对象代表一个包含类方法(例如new)的对象。

    例如:

    p (BasicObject.new()).instance_of?(BasicObject)
    

    打印出true,以及

    p (BasicObject.new()).instance_of?(Class)
    

    输出结果为false


    0

    你提供的所有示例本质上都是类。类本身也是对象。但是你没有看一个类的实例:

    p Object.new.class
    p Hello.new.class
    

    类定义了对象的形式,按照定义,一个类是一个类。但是当你将类实例化为对象时,对象就成为了新类型。但是你仍然可以看到对象的类本身就是类:

    p Hello.new.class.class
    

    你最后一句话可能应该是“...该对象的类的类本身是Class”或者“...该对象的类本身是一个Class的实例”。 - Jörg W Mittag

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接