I've been reading Metaprogramming Ruby and the object model is like the chicken or egg dilemma.
In Ruby 1.8, the Object class is an instance of Class. Module's superclass is Object and is an instance of Class. Class' superclass is Module, and it is an instance of Class (self-referential). Say class SomeClass; end is defined somewhere; SomeClass is an instance of Class, however its superclass is Object. Why does an instance of Class have Object as the superclass instead of nil?
Also, if Object is to exist, then Class has to exist, but then Module has to exist, but for Module to exist Object has to exist. How are these classes created?
Ruby is a pure object-oriented language, which means that in the Ruby language, everything is an object. These objects, regardless of whether they are strings, numbers, classes, modules, etc., operate in a system called The Object Model. Ruby offers a method called the object_id , which is available to all objects.
Everything in Ruby occurs in the context of some object. The object at the top level is called "main". It's basically an instance of Object with the special property that any methods defined there are added as instance methods of Object (so they're available everywhere).
In `ruby`, the body of an object is expressed by a struct and always handled via a pointer. A different struct type is used for each class, but the pointer type will always be `VALUE` (figure 1). In practice, when using a `VALUE`, we cast it to the pointer to each object struct.
Practically everything in Ruby is an Object, with the exception of control structures. Whether or not under the covers a method, code block or operator is or isn't an Object, they are represented as Objects and can be thought of as such.
Here is a complete Ruby Class Diagram (for Ruby 1.8): http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/
To help you understand the strange seemingly impossible self-reflexive nature of the class diagram it is useful to know that Class pointers and Super class pointers can be assigned at any time in the C API. That is, you can create an object (in the C API) and after-the-fact decide what the Class and Super class pointers point to.
Also, to understand the order of definition, look at Init_Object()
in object.c
(in Ruby 1.9)
rb_cBasicObject = boot_defclass("BasicObject", 0);
rb_cObject = boot_defclass("Object", rb_cBasicObject);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
metaclass = rb_make_metaclass(rb_cBasicObject, rb_cClass);
metaclass = rb_make_metaclass(rb_cObject, metaclass);
metaclass = rb_make_metaclass(rb_cModule, metaclass);
metaclass = rb_make_metaclass(rb_cClass, metaclass);
boot_defmetametaclass(rb_cModule, metaclass);
boot_defmetametaclass(rb_cObject, metaclass);
boot_defmetametaclass(rb_cBasicObject, metaclass);
Where rb_cBasicObject
is BasicObject
in Ruby, rb_cObject
is Object
in Ruby, and so on.
The easiest thing to consider is that everything in ruby is an Object. Everything else is a modification of this concept. So the class Class adds class like functionality, by modifying Object. As a result every Object is a class, etc.
The superclass of Object is nil. (Reference)
The superclass of Object is BasicObject (in 1.9) and the superclass of BasicObject is nil.
You can find some more details in the Ruby Hacking Guide: http://rhg.rubyforge.org/
Especially Chapter 04: Bootstrap
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With