eval confusion

P

Paolo Negri

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
http://jayfields.blogspot.com/2006/09/ruby-instanceexec-aka-instanceeval.html
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
 
N

nobu

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

Paolo Negri

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

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top