4 2.1.2 :...">

Undefined local variable or method after eval, if not previously declared

In Ruby

2.1.2 :068 >   a=1
 => 1
2.1.2 :069 > eval("a=4")
 => 4
2.1.2 :070 > a
 => 4
2.1.2 :071 > eval("b=4")
 => 4
2.1.2 :072 > b
NameError: undefined local variable or method `b' for main:Object

      

So the question is, why is variable 'b' going to be an 'undefined local variable or method', but variable 'a' is 4?

+3


source to share


2 answers


When you call a eval

lambda, you create a new scope for the code you are executing.



It will be like creating and executing a new lambda. If you declare a

before and then use a named variable a

in your lambda, you must use it. But if you don't declare b

before the lambda eval

will create its own variable and delete it at the end.

+1


source


 puts "outside binding #{binding.__id__}"
 a = 1
 puts "outside a #{a.__id__}"
 eval 'b="b"; puts "inside binding #{binding.__id__}"; puts "inside a #{binding.local_variable_get(:a).__id__}"; a="c"; puts "inside after a #{a.__id__}"'
 puts "outside after a #{a.__id__}"

      



follow the code above, you will see that the outer binding and the inner binding use different IDs. but share the same a. when we run eval, ruby ​​will copy the external binding, so it will use the same a; but b is defined in the internal binding, when eval is executed the internal binding is lost and hence b. In fact, the block area is the same as this one.

+1


source







All Articles