Nil or NameError


#1

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?

   Mage

#2

On Fri, 2006-02-03 at 21:58 +0900, Mage wrote:

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).


#3

Ross B. wrote:

NameError: undefined local variable or method `a’ for main:Object
I think it’s about the way Ruby decides whether ‘a’ is a method or a
if false then a = 5 end
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.

      Mage