3

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 the variable 'b' will be 'undefined local variable or method' but the variable 'a' equals 4 ?

2 Answers 2

1

When you call the eval lambda you create a new scope for the code that you execute.

It would be like to create and execute a new lambda. If you declare a before and then use a variable called a in your lambda, you shall use the same. But if you don't declare b before the lambda, eval will create its own variable, and will delete it at the end.

Sign up to request clarification or add additional context in comments.

2 Comments

Sidenote: there is no notion of “function” in ruby. The above is correct for procs/lambdas and wrong for methods.
In short: local variables really are local, that's why they are called local. In this case, b is local to the eval'd code.
1
 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__}"

run the code above, you can see that the outside binding and the inside binding is using different ids. but share the same a. when we run eval, ruby will copy the outside binding, so it will use the same a; but b is defined in the inside binding, when eval is done, inside binding is lost and so is b. Actually block scope is same as this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.