From: ts Date: 2002-06-01T18:14:20+09:00 Subject: Re: possible bug: stack dump with <<-String, #{...} and large loops >>>>> "C" == Christoph writes: C> It does not really retrieve it - it is just telling Ruby to interpret ``a'' C> as C> an initialized local variable. There is different way to see it :-) C> Without the `eval part' you would C> get a NameError, this difference is really surprising (to me at C> least;-). pigeon% ruby def aa(x) a = 1 end ^D pigeon% C> It is at least interesting that running the free form (no method) of the C> same Ruby snippet C> --- C> if x C> eval "p a" # no premonition C> end C> a = 1 C> --- C> also raises a NameError. it raise a NameError for `x' pigeon% cat b.rb #!/usr/bin/ruby if x eval "p a" end a = 1 pigeon% pigeon% b.rb ./b.rb:2: undefined local variable or method `x' for # (NameError) pigeon% Now this work pigeon% cat b.rb #!/usr/bin/ruby def x p "ruby has called me" true end if x eval "p a" end a = 1 pigeon% pigeon% b.rb "ruby has called me" nil pigeon% C> so basically it uses the `insight' (that `b' is a local variable and not C> dynamic C> variable ) gained at the end of the method body and to reinterpret the C> previous lines in that new light? No : ruby first compile the def, find the local variable `b' and store the name of this variable in a node of this def. When it has found the line `eval "p a"' it was interpreted as `eval("p a")' and ruby has created a node to call the method #eval When ruby call the def, it retrieve the node where are stored the name of the local variables and create a local variable `b'. When #eval is called, it compile the string, at this time ruby know that it exist a local variable `b' and it interpret "b = 1" like an access to this local variable. Without the line "b = 2", the local variable is not created when the method is called and eval "b = 1" will also be interpreted as an access to a *new* local variable Guy Decoux