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

···

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

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

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-forum.com/.

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-forum.com/.