# Nil or NameError

**URL:** <https://rubytalk.org/t/nil-or-nameerror/24591>\
**Category:** ruby-talk\
**Created:** [3 February 2006 12:58 UTC](https://rubytalk.org/t/nil-or-nameerror/24591 "2006-02-03T12:58:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mage](https://avatars.discourse-cdn.com/v4/letter/m/6f9a4e/32.png) [@Mage](https://rubytalk.org/u/Mage)\
**Post date:** [3 February 2006 12:58 UTC](https://rubytalk.org/t/nil-or-nameerror/24591/1 "2006-02-03T12:58:08Z")

</div>

Hello,

(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  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mage

---

<div class="post-metadata">

**Author:** ![Ross\_Bamford4](https://avatars.discourse-cdn.com/v4/letter/r/ea666f/32.png) [@Ross\_Bamford4](https://rubytalk.org/u/Ross_Bamford4)\
**Post date:** [3 February 2006 13:35 UTC](https://rubytalk.org/t/nil-or-nameerror/24591/2 "2006-02-03T13:35:23Z")

</div>

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:
> 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):8  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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?
> 
> --  
> Ross Bamford - rosco@roscopeco.REMOVE.co.uk

---

<div class="post-metadata">

**Author:** ![Mage](https://avatars.discourse-cdn.com/v4/letter/m/6f9a4e/32.png) [@Mage](https://rubytalk.org/u/Mage)\
**Post date:** [3 February 2006 14:11 UTC](https://rubytalk.org/t/nil-or-nameerror/24591/3 "2006-02-03T14:11:34Z")

</div>

Ross Bamford wrote:

> **···**
>
> > On Fri, 2006-02-03 at 21:58 +0900, Mage wrote:
> > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hello,
> > > 
> > > (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  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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?  
> > > &nbsp;&nbsp;&nbsp;  
> > > 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.
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mage
