This week, I would like to talk about Ruby’s ancestor tree. I was just curious that how methods are invoked in Ruby by order. I mean that which class method comes first to invoke and second and goes on. Let’s look at together step by step.
Singleton methods that are defined on only a single object. For example;
We have MyClass object class(below picture) and outside of this class we make a new instance which belongs to this class, and make this instance’s method called instance.my_method which this is how singleton class work. You class a method with that instance name. When we invoke this method. It will invoke that method and print it out “Singleton method”.
As you can see, It print it out “Singleton method”
So as a result of this example, we call this singleton method that belongs to only one unique instance.
Ruby is always look first singleton class to invoke a method.
Here, we have MyClass method, and we have a method called my_method which belongs to this class. we have the instance method of MyClass method. When we invoke this method it will print out “Instance method”.
So, Ruby will look on the Singleton class first, if there is any method called my_method there, it will invoke it, if there is no method in singleton, it will jump on to second step which is a its class method(in this case MyClass). If there is a my_method there, it will invoke it. As you can see above example. It invoked the method.
Let’s look at the this instance’s ancestor by typing instance.singleton_class.ancestors.
I’m using same example that we have done already.
First, as you can see we have this #<Class::#<MyClass:0x…..98>>, that instance itself, which make it singleton class and then Our created object MyClass, Object, Kernel, and BasicObject.
let’s do this with another example;
We have MySuperclass methods which is parent of MyClass method. We make an instance of MyClass.
When we call instance.singleton_class.ancestors
it will gives us [#<Class:#<MyClass:0….f8>>, MyClass, MySuperclass, Object, Kernel, BasicObject].
MySuperclass will be added to ancestor tree, it comes after MyClass.
Let’s move on to next step;
Let’s say that we have same method on MySuperclass and MyClass(in below picture I have some puts for MySuperclass and MyClass). When we invoke the method, Which will print it out, “MySuperclass” or “MyClass” ?
As you can see on output, It print out “MyClass”. Because Ruby first will look that there is any singleton class, then will look its class(which here is Myclass that we made an instance.) and then will go higher levels. Here Ruby invoked MyClass method. and It won’t invoke MySuperclass method. Because, Ruby won’t go to that level, if it find method in lower level.It will invoked and stop there.
Let’s do this example with super keyword on above line 24. It will invoke both first “MyClass” and then “MySuperclass”.
Let’s do another example with super;
So, Let’s add an singleton method on below line 32–35,and calls super over there as well. If you look at the output, Ruby will invoke singleton method first, then its method and then MySuperclass method.
Jav MacGavren explained the Lookup concept in a Ruby Conference very nicely and organized. Here is the link;