Pergunta

I am but confused right now after writing my repeated efforts at understanding the object model of ruby : following are my observations.

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 ....

What is going on here ? What lies at the apex of ancestry nil or NilClass or Object or Class ? How is Ruby's Object Model Organized.

What is a class and what is a object ? is Class a class or an object ? is Object an Object or a class ?

Foi útil?

Solução

Its a bit tricky. In Ruby everything is an Object (depending on your version).

  • Nil has its own NilClass, as it does not allow NilClass.new, which Object and Class allow. It is an object so you can call methods on it like nil.nil? etc.
  • Object is the highest Class, everything inherits from Object, even NilClass
  • Class is also an Object, it knows how to instantiate Objects from itself with the new method.

It is really weird at first, but I found the explanation from Dave Thomas quite revealing.

See: http://www.infoq.com/presentations/metaprogramming-ruby and http://pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming. The later is commercial.

Outras dicas

In ruby, a class object, is actually an instance of the Class class. class Foo is nearly identical to Foo = Class.new

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

Also, the class method is more design to be called on instances, not class objects.

class Foo
end

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

The semantics can be odd when calling on class objects. Though superclass works as you would expect on a class object.

So given all that lets explain these one by one:

>> Bird.class
=> Class

Bird the class object has a class of Class, since all class objects are instances of the Class class.

>> Class.class
=> Class

Yep even Class is an instance of Class. In this case it's actually a circular reference.

>> Class.superclass
=> Module

The Class class actually inherits from Module. After all, a class is simply a module that can be instantiated. But all non-instance functionality is pretty identical to modules.

>> Module.superclass
=> Object

Module inherits from Object. Just like everything in ruby if you go back far enough.

>> Object.class
=> Class

Again all class objects are instances of Class.

>> Object.superclass
=> nil

All ruby everything starts with Object. It is the base class for everything. Therefore it has no superclass.

>> nil.class
=> NilClass

nil is actually an instance of NilClass under the hood. NilClass defines methods that nil responds to. You can even add methods to NilClass if you want. There is also a TrueClass and a FalseClass.

>> NilClass.class
=> Class

Again all class objects are instances of Class.

>> NilClass.superclass
=> Object

NilClass inherits from Object like any class that does not specify an explicit superclass.

You can conclude the following from your example:

  1. Every name written in uppercase that appears in your example script points to a class (Bird, Class, Module, Object, NilClass).
  2. Every class is in turn an object of type Class (this is why X.class always returns Class in your example).
  3. X.superclass returns the base class of X.
  4. Object.superclass returns nil, because it has no base class! This does NOT mean that the base class of Object is NilClass or even nil (which is not a type, but an instance)
  5. The inheritance diagrams of the involved classes look something like:

    Object (top-level)      Object      Object
      |                       |           |
    Module                  Bird       NilClass
      |
    Class
    

Class returns a class for an object (and a class is an object). Superclass is the parent class of a (derived) class.

Please, see the Ruby Object Model.

I think you're getting confused about the difference between instances (like nil) and classes (like NilClass). It's reasonable to find it confusing because Ruby classes (NilClass) are also instances. Thus: a class is an instance. An instance is not a class though unless it is a class.

Here's a detailed hierarchy, which is made by ObjectGraph.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top