[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Nuby with instance_eval question

Geoff Barnes

8/27/2006 3:15:00 AM

Wondering why this works the way it does:

1 class Klass
2
3 attr_accessor :attr1
4
5 def initialize (&block)
6 chum = "chum_in_Klass"
7 instance_eval(&block) # Why does instance_eval pick up
self.attr1 from Klass but not 'chum'??
8 eval_attr1
9 end
10 def eval_attr1
11 @ok = self.attr1.call
12 end
13 end
14
15 chum = "chum_in_main"
16
17 foo=Klass.new {
18 self.attr1 = proc { chum }
19 }
20
21 puts foo.inspect # -> foo.ok = "chum_in_main"
22
23 chum="chum_in_main_again"
24 foo.eval_attr1
25
26 puts foo.inspect # -> foo.ok = "chum_in_main_again"

I have a constructor that uses a block to intialize the object's
members. Nested on the RHS of a member assignment is a proc block. The
proc block carries the value of chum from the "main" namespace, whereas
I expected it would take the chum from the Klass. I figured the proc
would not be evaluated and bound to a namespace until the passed block
was instance_eval'd in the constructpr, and thereby pick up a binding
from Klass... This makes my head hurt!

The observed behaviour is what I want but I didn't think it was
possible. I want to make sure I'm not taking advantage of a "bug" or a
language ambgiuity. If someone could make my eval/proc light bulb come
on it would be much appreciated..

Thanks

--
Posted via http://www.ruby-....

3 Answers

Matthew Johnson

8/27/2006 5:20:00 AM

0


> Wondering why this works the way it does:
>
> 1 class Klass
> 2
> 3 attr_accessor :attr1
> 4
> 5 def initialize (&block)
> 6 chum = "chum_in_Klass"
> 7 instance_eval(&block) # Why does instance_eval
> pick up
> self.attr1 from Klass but not 'chum'??
> 8 eval_attr1
> 9 end
> 10 def eval_attr1
> 11 @ok = self.attr1.call
> 12 end
> 13 end
> 14
> 15 chum = "chum_in_main"
> 16
> 17 foo=Klass.new {
> 18 self.attr1 = proc { chum }
> 19 }
> 20
> 21 puts foo.inspect # -> foo.ok = "chum_in_main"
> 22
> 23 chum="chum_in_main_again"
> 24 foo.eval_attr1
> 25
> 26 puts foo.inspect # -> foo.ok = "chum_in_main_again"
>
> I have a constructor that uses a block to intialize the object's
> members. Nested on the RHS of a member assignment is a proc
> block. The
> proc block carries the value of chum from the "main" namespace,
> whereas
> I expected it would take the chum from the Klass. I figured the proc
> would not be evaluated and bound to a namespace until the passed block
> was instance_eval'd in the constructpr, and thereby pick up a binding
> from Klass... This makes my head hurt!
>
> The observed behaviour is what I want but I didn't think it was
> possible. I want to make sure I'm not taking advantage of a "bug"
> or a
> language ambgiuity. If someone could make my eval/proc light bulb
> come
> on it would be much appreciated..

chum is a local variable in both places. instance_eval only affects
self and class variables, not local variables.

Matthew


e

8/27/2006 4:18:00 PM

0

Geoff Barnes wrote:
> Wondering why this works the way it does:
>
> 1 class Klass
> 2
> 3 attr_accessor :attr1
> 4
> 5 def initialize (&block)
> 6 chum = "chum_in_Klass"
> 7 instance_eval(&block) # Why does instance_eval pick up
> self.attr1 from Klass but not 'chum'??
> 8 eval_attr1
> 9 end
> 10 def eval_attr1
> 11 @ok = self.attr1.call
> 12 end
> 13 end
> 14
> 15 chum = "chum_in_main"
> 16
> 17 foo=Klass.new {
> 18 self.attr1 = proc { chum }
> 19 }

You are creating a closure here and, since 'chum' exists in
this scope (you would get an error otherwise), it is bound
here.

> 20
> 21 puts foo.inspect # -> foo.ok = "chum_in_main"
> 22
> 23 chum="chum_in_main_again"
> 24 foo.eval_attr1
> 25
> 26 puts foo.inspect # -> foo.ok = "chum_in_main_again"
>
> <snip />
>
> Thanks


--
Posted via http://www.ruby-....

Geoff Barnes

8/27/2006 6:03:00 PM

0

OK, thanks for the responses. Let's see if I got this right :

Blocks passed to instance_eval are still bound to where ever they were
declared but instance_eval will use instance & class variables where
ever required.




--
Posted via http://www.ruby-....