If the variable `a' is created in a scope local to the first #eval, then
this variable will no be accessible for the second #eval
puts val # -> 10
The problem is on this line. This is at *compile* time that ruby make the
difference between an access to a local variable or a method call,
i.e. ruby must make the choice between
(1) : puts val # I try to access the local variable `val'
(2) : puts val() # I call the method #val
this choice is made at compile time when ruby know *only* if it exist a
local variable and the rule is simple
* if a variable 'val' was previously found then it make the choice (1)
* otherwise it make the choice (2)
For example with
eval "val = 12"
p val
when it compile the second line, it has not yet executed the string for #eval this mean that at this step it don't exist a local variable `val'
and ruby consider that it's a method call, i.e.
eval "val = 12"
p val()
At runtime
* #eval will create a local variable `val'
* *but* in the second line, ruby will try to call the method #val
Now when you write
val = nil
eval "val = 12"
p val
when it compile the first line, it has found a new variable 'val'
when it compile the third line, it know that it exist a variable with the
name `val' and in this case it will create the node to access a local
variable.
At runtime, the 3 lines work with the same variable
p.s.: You'll have a similar problem with attribute writer
This is exactly the information I was looking for!
So even this works:
eval “val = 12”
val = val
p val
because at compile time the ‘val’ variable has been seen now.
I was just making sure that locals are only seen at compile-time, not
run-time and that there was no way of creating them at run-time (eval
compiles code).
If the variable `a’ is created in a scope local to the first #eval, then
this variable will no be accessible for the second #eval
puts val # → 10
The problem is on this line. This is at compile time that ruby make the
difference between an access to a local variable or a method call,
i.e. ruby must make the choice between
(1) : puts val # I try to access the local variable `val’
(2) : puts val() # I call the method #val
this choice is made at compile time when ruby know only if it exist a
local variable and the rule is simple
if a variable ‘val’ was previously found then it make the choice (1)
otherwise it make the choice (2)
For example with
eval “val = 12”
p val
when it compile the second line, it has not yet executed the string for #eval this mean that at this step it don’t exist a local variable `val’
and ruby consider that it’s a method call, i.e.
eval “val = 12”
p val()
At runtime
#eval will create a local variable `val’
but in the second line, ruby will try to call the method #val
Now when you write
val = nil
eval “val = 12”
p val
when it compile the first line, it has found a new variable ‘val’
when it compile the third line, it know that it exist a variable with the
name `val’ and in this case it will create the node to access a local
variable.
At runtime, the 3 lines work with the same variable
p.s.: You’ll have a similar problem with attribute writer