[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

eval confusion

Paolo Negri

10/3/2006 11:01:00 PM

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

2 Answers

Nobuyoshi Nakada

10/4/2006 12:18:00 AM

0

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

Paolo Negri

10/4/2006 7:58:00 AM

0

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