【问题标题】:Why is EVERYTHING an instance of Class in Ruby? [duplicate]为什么一切都是 Ruby 中的 Class 实例? [复制]
【发布时间】:2015-02-23 06:23:19
【问题描述】:

我不太了解 Ruby 对象模型。首先,Ruby 中的一切都是Class 的实例吗?这些都产生真:

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

其中BasicObject.classClass,而Class.is_a?(Object)

顺便说一句,使用 Ruby 2.0。

【问题讨论】:

    标签: ruby


    【解决方案1】:

    首先,Ruby 中的一切都是Class 的实例吗?

    不,不是所有东西都是Class 的实例。只有类是Class 的实例。

    有很多东西不是Class 的实例:例如,字符串是String 的实例,而不是Class 的实例。数组是Array的实例,整数是Integer的实例,浮点数是Float的实例,trueTrueClass的实例,falseFalseClass的实例,nilNilClass 的一个实例,等等。

    每个类都是Class 的实例,就像每个字符串都是String 的实例一样。

    如果ObjectClass 的超类,它怎么可能既是Class 的超类又是它的一个实例(Ruby 对象模型上的大多数图表都清楚地说明了这种层次结构)?

    魔法。

    就像在大多数其他语言中一样,有一些核心实体被简单地假设为存在。它们从天而降,凭空显现,神奇地出现。

    在 Ruby 中,其中一些神奇的东西是:

    • Object 没有超类,但你不能定义没有超类的类,隐式直接超类总是Object。 [注意:Object 可能存在实现定义的超类,但最终会有一个没有超类。]
    • ObjectClass 的一个实例,它是Object 的子类(这意味着间接地ObjectObject 本身的一个实例)
    • ClassModule 的子类,Class 的实例
    • ClassClass 的一个实例

    这些东西都不能用 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

    现在,我们可以覆盖BasicObject's、Object's、Module's 和Class's class 指向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

      【讨论】:

        【解决方案3】:

        您的所有示例都是定义类。类也是对象。但是你没有做的是查看一个类的实例:

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

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

        p Hello.new.class.class
        

        【讨论】:

        • 你的最后一句话可能应该是“……对象的类本身就是Class”或“……对象的类本身就是Class的一个(n个实例)”
        猜你喜欢
        • 2016-04-02
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 2021-06-07
        • 2010-10-22
        • 2015-04-16
        • 1970-01-01
        相关资源
        最近更新 更多