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.

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to 
rubyonrails-talk+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to