In fact, many of Ruby??™s metaprogramming idioms
are shamelessly stolen from either Lisp, Smalltalk, or Perl.
Delaying Method Lookup Until Runtime
Often we want to create an interface whose methods vary depending on some piece of
runtime data. The most prominent example of this in Rails is ActiveRecord??™s attribute
accessor methods. Method calls on an ActiveRecord object (like person.name) are translated
at runtime to attribute accesses. At the class-method level, ActiveRecord offers
extreme flexibility: Person.find_all_by_user_id_and_active(42, true) is translated
into the appropriate SQL query, raising the standard NoMethodError exception should
those attributes not exist.
The magic behind this is Ruby??™s method_missing method. When a nonexistent method
is called on an object, Ruby first checks that object??™s class for a method_missing
method before raising a NoMethodError. method_missing??™s first argument is the name of
the method called; the remainder of the arguments correspond to the arguments passed
to the method. Any block passed to the method is passed through to method_missing.
So, a complete method signature is:
24 | Chapter 1: Foundational Techniques
def method_missing(method_id, *args, &block)
...
end
There are several drawbacks to using method_missing:
??? It is slower than conventional method lookup. Simple tests indicate that method
dispatch with method_missing is at least two to three times as expensive in time
as conventional dispatch.
Pages:
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51