One second, though - what's metaprogramming, and what is method_missing?
Metaprogramming is writing code that writes code. In other words, you tell the interpreter to compose methods or do other code-writing-y things on the fly. The celebrated 'attr_accessor' method does just that; it takes one or more Symbols as an argument, and writes a method for each Symbol to assign and query an instance variable with the name defined by the Symbol. So `attr_accessor :name` is the same as:
def name
@name
end
def name=(name)
@name = name
end
Pretty neat, huh?
method_missing is, in my opinion, one of the coolest - yet most dangerous - features of Ruby. It is a method defined on every object that specifies the handling of methods whose name it doesn't recognize. The default handling is to raise a NoMethodError. But you can do this:
def method_missing(method_name, *args)
7
end
and then every unknown method will instead return "7" instead of raising an error. Why would you want to do this? I don't know. But maybe you would do this:
def method_missing(method_name, *args)
if method_name.to_s.start_with?("find_by_")
attribute = method_name.to_s[8..-1]
@players.find{ |player| player.send(attribute) == args[0] }
else
super
end
end
so you could do baseball_card_collection.find_by_homeruns(319) and, despite the method not being defined anywhere in your code, it will find the player with 319 homeruns. By the way, player.send(attribute) in this example is also an example of metaprogramming; it sends the method that shares the name of whatever attribute is passed in. This creates a lot of possibilities! Supposedly, however, objects with method_missing can present really annoying behavior and be notoriously difficult to debug, so it's often ill-advised to write a method_missing method.
P.S. Today I presented a technical blog post from my other blog; you can see it at http://amcaplan.wordpress.com/2014/02/19/lessons-from-a-failed-successful-gem/ (it's all about reflections on the experience of writing a gem, what I learned, what I could have done better, etc.).
Skills developed: Module writing, more ORMs, metaprogramming
No comments:
Post a Comment