Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
Ruby Foundations | 17

# Print the result of calling each method in turn
%w(one two three four five six).each do |number|
puts A.send(:"class_method_#{number}")
end

# >> Class method
# >> Also a class method
# >> Still a class method
# >> Yet another class method
# >> This works outside of the class definition
# >> You can open the metaclass outside of the class definition

This also means that inside a singleton class definition—as in any other class defini-
tion—selfrefers to the class object being defined. When we remember that the
value of a block or class definition is the value of the last statement executed, we can
see that the value ofclass <<objA; self; endisobjA’s singleton class. Theclass
<<objAconstruct opens up the singleton class, andself(the singleton class) is
returned from the class definition.


Putting this together, we can open up theObjectclass and add an instance method to
every object that returns that object’s singleton class:


class Object
def metaclass
class <<self
self
end
end
end

This method forms the basis of Metaid, which is described shortly.


Method missing


After all of that confusion,method_missingis remarkably simple. There is one rule: if
the whole method lookup procedure fails all the way up toObject, method lookup
is tried again, looking for amethod_missingmethod rather than the original method.
If the method is found, it is called with the same arguments as the original method, with
the method name prepended. Any block given is also passed through.


The defaultmethod_missing function inObject (rb_method_missing) raises an exception.


Metaid


why the lucky stiffhas created a tiny library for Ruby metaprogramming called
metaid.rb. This snippet is useful enough to include in any project in which meta-
programming is needed:*


Free download pdf