Method lookup and execution in Ruby
Wanna know how Ruby finds and executes a method?
First thing first, let know about methods. What are methods, I say. Ruby is a pure OO language. Meaning, everything is an object; even methods are.
The core philosophy of Object orientation is “message passing”.
OOP to me means only messaging,. — Alan Kay
So, basically the
methods are the messages you pass to objects.
Method definition in compile time
When class definition code (
class [ClassName]) is encountered, Ruby instantiates an object of
Class class with name
ClassName you supplied. And, the methods you defined will be defined inside the
ClassName definition. i.e. methods will be in the class’s blueprint. You can later pluck methods if you wish.
@instancevariables however are store in the object they belong to. And, only defined when the defining method is invoked. i.e. if constructor function is meant to define an @instance_var then the var will be defined during construction; otherwise won’t.
In the example above, when you invoke
cow.speak then Ruby will search the
cow object for
singleton methods called
speak , if not found will search the
Cow class for the
speak method. If still its not there then search
Printable module because its in the
superclass / ancestors chain. It continues to bubble up till it finds the method.
MySubclass.ancestors # => [MySubclass, MyClass, Object, Kernel, BasicObject]
In OO terms, basically its searching if this object is supposed to respond to that particular message; If yes, then how?
If the object is not able to respond, then
BasicObject#method_missing method is invoked. You can redefine what to do in that case for your object.
If the same method is defined in child and parent both, then one lower in hierarchy has higher priority. Means, it tries to return from search as soon as possible. If you wish to invoke method defined in parent then use
Executing the method found is little bit tricky. Found method might have mentions to @instance variables. And, you know that @instance vars are store in the objects. So, Ruby makes sure that the methods are executed in the Object’s binding.