Metaprogramming - dynamically defining class methods in Ruby

In Ruby 1.9.3 I need to create a few class instances which each have similar instance- and class-methods but which vary only by a few fixed parameters. The distinction of their class type is also important so I cannot simply use separate instances of the same class.

A simplified example looks like this.

module Animal
private
  def self.make_animal(name, legs, noise)
    klass = Class.new
    klass.const_set(:NUM_LEGS, legs)
    klass.class.send(:define_method, :scream) { noise.upcase + '!' }
    Animal.const_set(name, klass)
  end
  make_animal :Tiger, 4, 'roar'
  make_animal :Human, 2, 'derp'
end

This seems to work fine except that the variables used in the block which dynamically defines the "scream" method are bound at runtime of the "scream" method instead of runtime of the "make_animal" method.

Animal::Human::NUM_LEGS # => 2 -- ok
Animal::Tiger::NUM_LEGS # => 4 -- ok
Animal::Human.scream # => "DERP!" -- ok
Animal::Tiger.scream # => "DERP!" -- fail!

How can I modify the above code so that the Tiger screams "ROAR!"?

[Note] I really do need to maintain the goofy OO structure in the example for reasons that are too involved to describe here. I'm interested only in learning how to programmatically define class methods on dynamically defined classes with parameterized method implementations.

This question and all comments follow the "Attribution Required."

All Answers

Answers Loading...
Leave a Reply
You must be logged in to post a answer.
About the author