Eval confusion

Hi there

I need some help understating this behaviour.
I’ve read the docs of define_method but I’m still missing how it exactly
works.
Here’s some code I’ve written trying to use to understand

cat script.rb

#!/bin/ruby
class DefMethod
M_COLLECTION = (‘a’…‘c’)
M_COLLECTION.each do |alpha|
define_method(alpha) {
block_given? ? puts(yield(alpha)) : puts(alpha)
}
end
end

class EvalMethod
DefMethod::M_COLLECTION.each do |alpha|
class_eval <<-ENDEVAL
def #{alpha}
block_given? ? puts(yield(“#{alpha}”)) : puts(“#{alpha}”)
end
ENDEVAL
end
end

defobj = DefMethod.new
evalobj = EvalMethod.new
print “====no block====\n”
defobj.a
evalobj.a
print “====with block====\n”
defobj.a {|x| x + ’ << block given!‘}
evalobj.a {|x| x + ’ << block given!’}

Basicly I’m defining 2 class with 3 method (a,b,c) each in the first
class I use define_method and in the second class_eval.
Now, the output of this script is

ruby script.rb
====no block====
a
a
====with block====
a
a << block given!

So the ‘a’ method is sensible to the block only in the version defined
with class_eval.
After reading the usage of define_method here

I can understand that my first class is basicly wrong but I would
still understand what happens behind the scenes, and how I can manage
to ‘see’ the block using define_method.

Thanks.

Paolo

Hi,

At Wed, 4 Oct 2006 08:00:32 +0900,
Paolo N. wrote in [ruby-talk:217920]:

#!/bin/ruby
class DefMethod
M_COLLECTION = (‘a’…‘c’)
M_COLLECTION.each do |alpha|
define_method(alpha) {
block_given? ? puts(yield(alpha)) : puts(alpha)

This block_given? sees the context where define_method is
called, that is defining DefMethod and always false.

}

end
end

In 1.9, you have to write as:

define_method(alpha) {|&block|
  block ? puts(yield(alpha)) : puts(alpha)
}

No way in 1.8.

Thank you for replying and for the note on 1.9 very interesting!

Paolo