(1..2).each { if 1 == 2 then a = 5 else puts a end }
nil
(1..2).each { if 1 == 2 then b = 5 else puts a end }
NameError: undefined local variable or method `a' for main:Object
from (irb):8
Okay, I understand what happend, but I am wondering. Is this okay? Is there any philosophical reason behind it or it's just easier for the interpreter?
I think it's about the way Ruby decides whether 'a' is a method or a
local variable. It uses a heuristic and looks for stuff like argument
list and so forth, but in cases like this it comes down to whether Ruby
has 'seen an assignment' to that symbol. Note that this doesn't mean
*executed* an assignment, just seen (parsed? compiled?) one.
This is a simplified example:
puts a
# => -:2: undefined local variable or method `a' for main:Object
if false then a = 5 end
puts a
# => nil
In the first case, because Ruby hasn't seen any previous reference to
'a', the NameError is raised.
In the second case, I guess Ruby creates a local slot for 'a' as it
compiles the if false... expression, initialised to nil, and since that
is never executed, the local stays nil (but *is* known as a local, Ruby
'remembers' seeing it being assigned to, even though it was never
executed).
···
On Fri, 2006-02-03 at 21:58 +0900, Mage wrote:
Hello,
(1..2).each { if 1 == 2 then a = 5 else puts a end }
nil
nil
(1..2).each { if 1 == 2 then b = 5 else puts a end }
NameError: undefined local variable or method `a' for main:Object
from (irb):8
from (irb):8
Okay, I understand what happend, but I am wondering. Is this okay? Is
there any philosophical reason behind it or it's just easier for the
interpreter?
(1..2).each { if 1 == 2 then a = 5 else puts a end }
nil
(1..2).each { if 1 == 2 then b = 5 else puts a end }
NameError: undefined local variable or method `a' for main:Object
from (irb):8
Okay, I understand what happend, but I am wondering. Is this okay? Is there any philosophical reason behind it or it's just easier for the interpreter?
I think it's about the way Ruby decides whether 'a' is a method or a
local variable. It uses a heuristic and looks for stuff like argument
list and so forth, but in cases like this it comes down to whether Ruby
has 'seen an assignment' to that symbol. Note that this doesn't mean
*executed* an assignment, just seen (parsed? compiled?) one.
This is a simplified example:
puts a
# => -:2: undefined local variable or method `a' for main:Object
if false then a = 5 end
puts a
# => nil
In the first case, because Ruby hasn't seen any previous reference to
'a', the NameError is raised.
In the second case, I guess Ruby creates a local slot for 'a' as it
compiles the if false... expression, initialised to nil, and since that
is never executed, the local stays nil (but *is* known as a local, Ruby
'remembers' seeing it being assigned to, even though it was never
executed).
I thought that it can be purposive. I have written a buggy code, which would either throw an exception or generate a bad result in other languages. However it works perfectly in Ruby.
While I never want to write inperfect code, I had to notice that Ruby's scope and variable handling "fixed" my error.