Nuby with instance_eval question

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

self.attr1 from Klass but not ‘chum’??
18 self.attr1 = proc { chum }
members. Nested on the RHS of a member assignment is a proc
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

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.

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"

Thanks