Ross Bamford
2/3/2006 1:35:00 PM
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?
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).
--
Ross Bamford - rosco@roscopeco.REMOVE.co.uk