Understanding the Ruby object model
Not a very long time ago, I found the Ruby object model very confusing. Part of my problem was that I was trying to model the relationships as a directed acyclic graph, whereas in reality, the model contains cycles. I’m guessing that others have found this confusing, so I’m going attempt to explain how it works in a way that my past self would have understood! Note that this is a basic explanation, and glosses over higher-level concepts like the eigenclass/metaclass (I’ll leave that for a later post).
Different things in Ruby
There are just a few things that exist in Ruby that you need to understand to really grok its object model.
Objects
Everything is an object. You can’t get very far into Ruby-land without hearing that phrase. It’s true though, everything in Ruby is an object. The interesting thing is how those objects are linked together and classified.
Classes
All objects are instances of a class. There are three special classes that are the key to understanding the Ruby object model: Object
, Module
and Class
. More on them later.
Relations
Like I said before, it’s the links between the different objects that explain how the Ruby object model works.
Instance of/class
All objects have a class - they are instances of that class. That means that whenever you have a class, you can call .new
on it to get an instance. And whenever you have an instance, you can call .class
to get its class. This seems obvious, but it can get confusing when you remember that everything is an object, and so everything is an instance of a class.
Superclass/subclass
All classes have a link to a superclass. If you don’t explicitly inherit from another class in a class definition, that class will inherit directly from the Object
class.
How they fit together
Here’s some code to play with:
class Animal
end
class Dog < Animal
end
fido = Dog.new
Once you know what the pieces and the relations are, it’s fairly straightforward to piece them together. All classes are an instance of Class
. That includes the class Class
, so there’s a circular relation there (which isn’t a problem).
Dog
will basically have the following inheritance hierarchy (the superclass links):
Dog < Animal < Object < BasicObject
(Ruby 1.9 introduced BasicObject
as Object
’s superclass.)
The Class
class has the following inheritance hierarchy:
Class < Module < Object < BasicObject
Anything that’s a class (so BasicObject
, Object
, Module
, Class
, Animal
and Dog
here) has Class
as its class - they’re all instances of Class
. Any other objects have their own classes. So fido
above will have a class of Dog
, 3
has a class of Fixnum
, “an awesome string” has a class of String
, etc. All those classes inherit from Object
ultimately (although classes like Fixnum
have their own complex inheritance hierarchies).
To finish things off, here’s a little diagram of what I’ve just described, showing all the class and superclass links.