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 P.ming
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.