hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Monday

2005.05.30

Hatching New Methods in Mid-air #

by why in inspect

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.