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
====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 Negri 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.

···

--
Nobu Nakada

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

Paolo

···

On 04/10/06, nobu@ruby-lang.org <nobu@ruby-lang.org> wrote:

Hi,

At Wed, 4 Oct 2006 08:00:32 +0900,
Paolo Negri 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.

--
Nobu Nakada