method\_missing rules! You probably have a good idea what it does, if you call a method on an object that doesn’t exist, before giving up and stacking, it will call method\_missing. Then you can grab the method names and parameters, jack around with them, and call a different method (or not).
I recently used method\_missing to add some syntactic sugar to a project at work, it was simple. My task was to queue method calls the user doesn’t care about. I quickly wrote a queuing daemon to asynchronously run additional code outside the context of mongrel. The syntax for creating QueueItems was ugly:
QueueItem.push(AuditWebService, :send_audit, audit_instance).save
I cleaned this up by implementing a quick mixin, that you include in any module or class:
module Queuable
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def method_missing(method, *args)
my_method = method.to_s
test_for_queue = my_method.match(/\Aqueue_(.+)\Z/)
if test_for_queue && self.respond_to?(test_for_queue[1])
QueueItem.push(self, test_for_queue[1], args[0])
elsif self.is_a?(Class)
super
else
raise NoMethodError.new(”no method error #{method}”, self)
end
end
end
end
I am not going to explain the ruby voodoo in the about module, it is beyond the scope of this post, but with the method_missing trick you get:
AuditWebService.queue_send_audit(audit_instance).save
While I haven’t saved a lot of code it reads much more naturally.
There are a few caveats, if you don’t can’t handle the **method\_missing**, you should always call super, to try another implementation of **method\_missing**. It is important that you don’t change the **method** parameter. When I converted it from a symbol to a string to do regex on it, I started to get all sorts of crazy errors like:
ArgumentError: no id given
That was a little difficult to track down, I hope this helps someone else.
Ah winner, I had no idea what that ‘no id given’ error was, your solution fixed it