I stumbled across this TIL because I've been looking up advanced topics in a bid to learn new things and deepen my knowledge of Ruby & Rails.
Super useful preamble
- Everything in Ruby is an object.
- All Ruby objects have an ancestor chain.
BasicObjectis always at the end of that chain. - All classes have a
Classancestor. Classinherits fromModulewhich means every class is sort of a module. "Sort of" because unlike actual modules you can't mixin classes.Moduleadds in instantiation, properties etc to classes.
Method lookup in Rails is possible because of a few fields all Ruby objects, classes, and modules have.
objects
class: A pointer to the class object of the object. For example, for an Fish class, calling theclassmethod returnsClass.iv_tbl(Instance Variable Table): a hashtable containing the instance variables of the object.
classes, modules
m_tbl(Method Table) - A hashtable containing all the class or module's instance methods.super- A pointer to the class or module's superclass (direct ancestor). You can lookup the ancestors of an object by calling theancestorsmethod on that object.
How method lookup works
- Ruby follows the object's
classpointer and checks its method table (m_tbl) for a match. - If there's no match, it follows the object's
superpointer and checks its method table for a match. Ruby continues up thesuperancestor chain, looking into each ancestor's method table for a match. - If there is still no match, Ruby invokes
method_missingon the original object. FYI,method_missingis a method so it'll undergo this lookup process too until it is found and invoked.