This post originated from an RSS feed registered with Ruby Buzz
by Red Handed.
Original Post: Hatching New Methods in Mid-air
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
Ken Miller sent in a very interesting class, which creates new methods as they are needed. And, also, the respond_to? method is hacked to respond positively in these cases. I could see this kind of thing going into Rails so you can Student.find_classes or Student.find_grades. That sort of thing.
class MethodMagic
alias_method :old_respond_to?, :respond_to?
def respond_to? (method, include_private=false)
old_respond_to?(method.to_sym, include_private) ||
create_dynamic_method(method)
end
alias_method :old_method_missing, :method_missing
def method_missing(method, *args)
if create_dynamic_method(method)
send(method.to_sym, *args)
else
old_method_missing(method)
end
end
# If the method name conforms to our rigorous specifications,
# create a new body on the fly and define the sucker
def create_dynamic_method(method)
if method.to_s.match /^find_by_/
self.class.send(:define_method, method.to_sym) { |*args|
puts "Called #{method}(#{args.join ", "})"
}
true
else
false
end
end
# just here as an example of a normal method
def find; end
end
mm = MethodMagic.new
p mm.respond_to?(:find) # => true
p mm.respond_to?(:find_by_letters) # => true
mm.find_by_letters("a", "b", "c") # prints 'Called find_by_letters(a, b, c)'
mm.find_by_numbers(1, 2, 3) # prints 'Called find_by_numbers(1, 2, 3)'
p mm.respond_to?(:poopy) # => false
mm.poopy # raises NoMethodError
What about you? Do you have any metaprogramming tricks for us? If nothing else, read Ruby/X11 source and get back to me.