1

在写下我反复努力理解 ruby​​ 的对象模型之后,我现在很困惑:以下是我的观察。

class Bird
  def speak
   puts "tweet tweet"
  end
end

>> Bird.class
=> Class
>> Class.class
=> Class
>> Class.superclass
=> Module
>> Module.class
=> Class
>> Module.superclass
=> Object
>> Object.class
=> Class
>> Object.superclass
=> nil
>> nil.class
=> NilClass
>> NilClass.class
=> Class
>> NilClass.superclass
=> Object 
and keeps going on ....

这里发生了什么 ?祖先 nil 或 NilClass 或 Object 或 Class 的顶点是什么?Ruby 的对象模型是如何组织的。

什么是类,什么是对象?Class 是类还是对象?对象是对象还是类?

4

5 回答 5

6

在 ruby​​ 中,一个类对象,实际上是Class该类的一个实例。 class Foo几乎相同Foo = Class.new

MyClass = Class.new
instance = MyClass.new
puts instance # => #<MyClass:0x100c14b38>

此外,该class方法更多地设计为在实例上调用,而不是在类对象上调用。

class Foo
end

f = Foo.new
puts f.class # => Foo

调用类对象时语义可能很奇怪。尽管superclass在类对象上可以正常工作。

因此,鉴于所有这些,让我们一一解释:

>> Bird.class
=> Class

Bird类对象的类为Class,因为所有类对象都是该类的实例Class

>> Class.class
=> Class

是的,甚至ClassClass. 在这种情况下,它实际上是一个循环引用。

>> Class.superclass
=> Module

该类Class实际上继承自Module. 毕竟,类只是一个可以实例化的模块。但是所有非实例功能都与模块完全相同。

>> Module.superclass
=> Object

Module继承自Object。就像红宝石中的所有内容一样,如果您回溯得足够远。

>> Object.class
=> Class

同样,所有类对象都是Class.

>> Object.superclass
=> nil

所有 ruby​​ 都以Object. 它是一切的基类。因此它没有超类。

>> nil.class
=> NilClass

nil实际上是NilClass引擎盖下的一个实例。 NilClass定义nil响应的方法。如果需要,您甚至可以添加方法NilClass。还有一个TrueClass和一个FalseClass

>> NilClass.class
=> Class

同样,所有类对象都是Class.

>> NilClass.superclass
=> Object

NilClass继承自Object任何未指定显式超类的类。

于 2011-08-31T22:49:15.270 回答
2

您可以从您的示例中得出以下结论:

  1. 示例脚本中出现的每个大写名称都指向一个类 ( Bird, Class, Module, Object, NilClass)。
  2. 每个类又是一个类型的对象Class(这就是为什么X.class总是Class在您的示例中返回)。
  3. X.superclass返回 的基类X
  4. Object.superclass返回nil,因为它没有基类!这并不意味着Object 的基类是NilClass或什至nil(不是类型,而是实例)
  5. 所涉及类的继承图如下所示:

    Object (top-level)      Object      Object
      |                       |           |
    Module                  Bird       NilClass
      |
    Class
    
于 2011-08-31T22:43:46.480 回答
2

它有点棘手。在 Ruby 中,一切都是对象(取决于您的版本)。

  • Nil 有自己的 NilClass,因为它不允许 NilClass.new,而 Object 和 Class 允许。它是一个对象,所以你可以像 nil.nil 一样调用它的方法?等等
  • Object是最高的Class,一切都继承自Object,甚至是NilClass
  • 类也是一个对象,它知道如何使用新方法从自身实例化对象。

一开始真的很奇怪,但我发现 Dave Thomas 的解释很有启发性。

请参阅: http: //www.infoq.com/presentations/metaprogramming-rubyhttp://pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming。后者是商业的。

于 2011-08-31T22:43:48.617 回答
1

Class返回对象的类(并且类是对象)。超类是(派生)类的父类。

请参阅Ruby 对象模型

于 2011-08-31T22:45:56.240 回答
0

我认为您对实例(如nil)和类(如NilClass)之间的区别感到困惑。感到困惑是合理的,因为 Ruby 类 ( NilClass) 也是实例。因此:一个类是一个实例。一个实例不是一个类,除非它是一个类。

这是一个详细的层次结构,由ObjectGraph制作。

于 2011-08-31T22:45:04.393 回答