Understanding the “chain”
In my last article, I explained where the various elements of an object were located. Now it’s time to understand what happens at run time when you write the following :
Ahh… A method call! Ruby knows what to do in this situation. Remember that inside “obj” resides a reference to MyClass? Well, ruby follows that reference and looks at the methods in there. It tries to find “my_instance_method”… and it finds it! The call succeeds and everyone in the world is happy, dancing hands in hands like shameless hippies.
Now, if we write :
Once again, ruby follows the reference to “MyClass” and looks for the method “display”. Unfortunately this time, it doesn’t find it. Instead of crying, ruby doesn’t give up and looks for the method in any module that could have been mixed into MyClass (I’ll talk about modules in another post)… but still it can’t find it. Determined as we know it, ruby now follows the reference to the super class (Object) in hope to find that method. Victory, the method is there! The call succeeds.
Once again, ruby follows the reference to MyClass and tries to find “my_class_method”, it isn’t there. It looks in any mixed in module, it isn’t there. It looks in the super class, it isn’t there. It looks in any module that could have been mixed in the super class, it still isn’t there. Now the chain is over, because “Object” has no super class. Ruby invokes “method_missing” and the story ends in a very bad way (people are crying and sobbing to the point that it gets quite embarassing).
But I want to access that class method!
Ah! That looks better. Now the starting point is MyClass instead of obj. Ruby follows the reference to the class of MyClass, let’s call it MetaMyClass (if you hear the expression meta class for the first time, have a look at the first part). Once comfortable inside MetaMyClass, it looks for the method “my_class_method” and guess what? It finds it! The call succeeds.
The chain for class methods
The last paragraph reveals something interesting : there exists a chain for class methods. Now, what if we write :
Since ruby won’t find the method “name” inside MetaMyClass (it’s just a fictional name I gave to the meta class… it isn’t a real ruby class name), what will it do? It will look into the super class of MetaMyClass, which we’ll call MetaObject. MetaObject contains the method “name”… so the call will succeed!
So that’s how this 2-part serie ends. An important but not so obvious thing is the concept of meta classes. To understand their purpose, just tell yourself once again that classes are objects, it’s the key really. If classes are objects, they need a place to store their own methods like any other objects. “obj” stores it’s methods in “MyClass”, “MyClass” stores it’s methods in it’s associated meta class.