Sunday, January 25, 2009

Can I just say how much I love method_missing?

I wanted to follow up on my previous explorations with ShoeQuery to add some helper methods to access pieces of shoes functionality... thinking I'd have to add pieces one by one. However, it turns out that due to the magic of method_missing, I was able to add access to basically all of them with a single 22-line method. It looks like:


def method_missing(method, *args, &block)
if args.empty? && !block_given?
# if you have no arguments and no block, think of it as a query
# and return the answer for the first element.
if first.respond_to? method
return first.send(method)
else
return elem.style(method)
end
elsif block_given?
each {|elem| elem.send(method, *args, &block)}
else
# Otherwise, think of it as a setter
setter = "#{method}=".to_sym
if first.respond_to? setter
each {|elem| elem.send(setter, *args, &block)}
else
each {|elem| elem.style(method => args[0], &block)}
end
end
self
end


And now, thanks to this I can write lines in shoes as follows:


# find all paragraphs, change their text to 'all ps', and color
# them red
shoe_query('para').text("all ps").stroke(red)



# replace the click handlers on all buttons
shoe_query('button').click do
para "All your button are belong to us now
end

No comments:

Post a Comment