Method Missing
August 15th, 2007
For the last year I’ve been having a love affair with Ruby’s method_missing. Ryan Heneise was the first to show me the power of this method, when working on Moral Metric together. I’m going to show you a very simple example, and perhaps in future snips more complicated uses, of method_missing.
Let’s say we have an application that keeps track of all the super-heroes and villains. We have one table for the super-heroes and villains and a join table for super powers. We want to have clean syntax to return a boolean value for a hero/villain when check if they have a certain power. e.g.
wolverine.has_claws? wolverine.can_heal?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def check_powers(power) self.powers.detect { |power| power.name == power } ? true : false end def method_missing(method, *args) if find = method.to_s.match(/^has_(\w*)\?$/) self.check_powers(find[1]) elsif find = method.to_s.match(/^can_(\w*)\?$/) self.check_powers(find[1]) else super end end |
The first method does our basic check to see if that power exists and returns a boolean value.
method_missing does two matches here. The first checks to see if there is a match for has_something? and the second does a match for can_something? Both take the “something” and send it to our check_powers method to do our detect. Yes, it is that simple, but oh so cool! And, if method_missing doesn’t find what we were looking for, it sends it on up the chain for rails to handle. Neat, huh?
We can get really nice syntax by using method_missing and DRY up our code, quite a bit as well. Definitely a great little nugget to use.
2 Responses to “Method Missing”
Sorry, comments are closed for this article.


August 15th, 2007 at 08:56 AM
I’m somewhat new to method_missing, but I think it’s among the nicest features of Ruby.
I’m working on a golf application and wanted to be able to access individual holes, without using a finder or declaring 18 methods corresponding to the 18 holes. So I used method_missing, which allowed me to do course.holes._18 and so forth. Although, I later changed it to course.holes18 instead, using :[] as an alias_method for find.
It seems like it’s always a good idea to resort back to super when using method_missing… do you think so?
Also, is it hard to get line numbers to show up in your Ruby syntax highlighting?
August 15th, 2007 at 05:26 PM
Ryan: Yes, I’d always, always else back to super so that specific rails functionality will remain open to being used. The Rails core does use method_missing.
It’s really easy to get numbers to show up, do a google search for Dan Webb’s syntax highligher. It’s a great JS piece to use – which is what I use.