Nuby with instance_eval question

Discussion in 'Ruby' started by Geoff Barnes, Aug 27, 2006.

  1. Geoff Barnes

    Geoff Barnes Guest

    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/.
     
    Geoff Barnes, Aug 27, 2006
    #1
    1. Advertising


  2. > 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
     
    Matthew Johnson, Aug 27, 2006
    #2
    1. Advertising

  3. 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/.
     
    Eero Saynatkari, Aug 27, 2006
    #3
  4. Geoff Barnes

    Geoff Barnes Guest

    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/.
     
    Geoff Barnes, Aug 27, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Van Jacques

    nuby question re a method

    Van Jacques, Dec 10, 2003, in forum: Ruby
    Replies:
    0
    Views:
    90
    Van Jacques
    Dec 10, 2003
  2. Boris \BXS\ Schulz

    nuby question: f.rename(x,y) does not work

    Boris \BXS\ Schulz, Jan 3, 2004, in forum: Ruby
    Replies:
    4
    Views:
    96
    Boris \BXS\ Schulz
    Jan 3, 2004
  3. Harry
    Replies:
    2
    Views:
    103
    Samuel Kvarnbrink
    Jan 26, 2004
  4. Edwin Eyan Moragas

    nuby question: question marks in method names

    Edwin Eyan Moragas, Aug 30, 2004, in forum: Ruby
    Replies:
    0
    Views:
    143
    Edwin Eyan Moragas
    Aug 30, 2004
  5. Chris Hall
    Replies:
    1
    Views:
    100
    Stefano Crocco
    Sep 14, 2007
Loading...

Share This Page