Nuby with instance_eval question

G

Geoff Barnes

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
 
M

Matthew Johnson

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

Eero Saynatkari

Geoff said:
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.
 
G

Geoff Barnes

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.
 

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

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top