I’m reading Metaprogramming Ruby and just want to clear something up about the following paraphrased code:
class MyClazz
def self.my_class_method(name)
define_method(name) {
# do stuff
}
end
my_class_method :foo
my_class_method :bar
end
# The code above generates instance methods:
# def foo
# do stuff
# end
# def bar
# do stuff
# end
Q1
My first question regards the two method calls at the end of the file: my_class_method :foo and my_class_method :bar. Am I right in thinking that they are both invoked automatically when a MyClazz object is instantiated?
Q2 When Ruby generates these methods (def foo and def bar), it will put them in MyClazz’s eigenclass, even though they are instance methods. So does this mean that Ruby looks to the eigenclass for both class and instance methods when needed?
I just want to clear that up before I move too far into the book.
Answer 1: (short) They are invoked when ruby instantiate
MyClassinstance (of typeClass).(long) When Ruby interpreter sees a class definition (
class MyClazz) it instantiate an instance of this class and evaluate all the code inside class definition.In your case
MyClazzis a constant that holds a refference to the object of classClass. And when Ruby initialize it, it execute code inside class definition – defines singleton methodmy_class_methodof thisClassinstance and executes methodmy_class_methodtwice in the context of thisClassinstance.Answer 2: (short)
Module#define_methodprivate method adds method to the method table ofClassinstance (method table holds instance methods of the class). It does not affect eigenclass of istance object/class object.(long) When you call instance method on the object, Ruby first looks this method in the eigenclass of this object, then in the superclass of eigenclass (it will be a
Classobject of the object’s class). But it will not look in the eigenclass ofMyClazzobject.
Example:
obj.foowill look forfoomethod definition in eigenclass ofobjobject, then will look for instance methods ofMyClass(instance of classClass), then in the superclass ofMyClassobject (in your case this isObjectclass) etc.MyClass.my_class_methodwill look formy_class_methodmethod definition in the eigenclass ofMyClassobject (sidenote: eigenclass of a class sometimes iscalled a metaclass) and it will find it here and will add
bazinstance method to the classMyClass.