One shortcoming of define_method is that it does not allow you to specify a method body that expects a block. If you need to dynamically create a method that accepts a block, you will need to use the def statement within class_eval. Here's a trivial example:
class Module def acts_as_thing(name, &block) self.class_eval { define_method(name, &block) } end end
class Thing #using define_method does not allow us to specify a method body that expects a block, because the block used in define method becomes the method body itself, not a block passed to a method body. acts_as_thing :animals do puts "animal group" end
def initialize(name) @name = name end end
#To address the limitations of define_method, that is, to dynamically create a method that accepts a block, we need to use the def statement with class_eval. Thing.class_eval { def spell_out_name yield @name end }
thing = Thing.new("dog") thing.animals # => animal group thing.spell_out_name {|name| puts "The name is #{name}."} # => The name is dog.
Here's my question. I am reading a book called The Ruby Programming Language. It says the following:
"If the method you are creating is sufficiently dynamic, you may not be able to pass a block to class_eval and will instead have to specify the method definition as a string to be evaluated."
I'm not sure what they are talking about here. What does it mean by "sufficiently dynamic"? In my example above, I proved that a method defined within the context of class_eval can accept a block.