Ruby is a fully object-oriented programming language. But what does that really mean ?

In this series of articles, we’ll try to demystify the Ruby Object Model.

Before to start

I’m thrilled to share with you our latest project: Fun Facts about Ruby — Volume 1

Please feel free to spread the word and share this post! 🙏

Thank you for your time!

The Ancestor Chain

The ancestors method returns an Array that represents the ancestor chain.

The ancestor chain is the representation of the class hierarchy in Ruby.

In order, it contains:

The calling class

its included modules

its parent class

the included modules of its parents class

the parent class of its parent class

etc..

Here is an example of the ancestor chain of the Array class

irb> Array.ancestors # Array's ancestor chain

=> [Array, Enumerable, Object, Kernel, BasicObject]

irb> Array.included_modules # Array included modules

=> [Enumerable, Kernel]

irb> Array.superclass # the parent class

=> Object

irb> Array.superclass.included_modules # parent's included modules

=> [Kernel]

irb> Array.superclass.superclass # the grandparent class

=> BasicObject

Array::included_modules returns an array that contains all the modules included in the ancestor chain. This is why the Kernel module is included in the array for Array.included_modules .

Ancestor Chain and Method Call

When you call a method inside of your object, what Ruby does is to first check if this method exists inside the self context. If it doesn't find it there, it continues up the ancestor chain until it finds the method.

class Tiger

def to_s

"roar"

end

end irb> Tiger.new.to_s

=> "roar" # calls the #to_s method defined in the Tiger class

irb> Tiger.inspect

=> "#<Tiger:0x007f>" # calls the #inspect method defined in Object

Object class hierarchy

Object is the default root class in Ruby. This means that any new class inherit from object by default

class Child

end Child.superclass

=> Object

So, what’s the purpose of this class ?

If we call the ancestors method on Object it’ll return the following ancestor chain

irb> Object.ancestors

=> [Object, Kernel, BasicObject]

BasicObject

The BasicObject class is the top parent of all class. It contains a bare minimum of methods for object creation and object comparison.

Kernel

The Kernel module is included in the Object class. It contains all the “object manipulation” logic.

Object

As the Kernel module contains the majority of the methods, Object is more used as an interface (for its name) by all its children.

The main object

When a new program starts, Ruby automatically creates the main object which is an instance of the Object class. main is the top-level context of any program. This is probably a nod to the C language (as the main() function is the entry point of any C program and that Matz loves C)

irb> self

=> main

irb> self.class

=> Object

main is the top-level scope of any ruby program. This means that any instruction out of a class/module scope is executed in the main context

irb> puts "main context"

=> main context

Here, the puts method refers to the private Kernel#puts method. We have access to this method because main is an instance of Object which includes Kernel .

Now, let’s explicitly try to access the puts method via self (which refers to the main object instance).

irb> self.puts "main context"

NoMethodError: private method `puts' called for main:Object

This error is due to the fact that a private method cannot be called with a receiver ( self in this case).

Calling self.puts is like calling main.puts . So, We try to call puts outside of its class context.

In other words, we try to call a private method as a public one.

Conclusion

Ruby is a fully oriented-object language because from the entry point (the main context) to the end of your program you’ll be scoped at least in the main object.

Next article: If you don’t know that Module is an instance of the Class class, stored in a constant and whose instances cannot be instantiated then you’ll probably learn something :)

Voilà !

ONE MORE THING ⬇

Feel free to subscribe here: www.rubycademy.com