# Weird variable scope behaviour

**URL:** <https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276>\
**Category:** Ruby\
**Created:** [September 23, 2007, 12:36am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276 "2007-09-23T00:36:19Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 23, 2007, 12:36am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/1 "2007-09-23T00:36:19Z")

</div>

I just wrote some code that shouldn’t have worked, in my estimation, but  
it did, anyway. While this was a pleasant surprise, I prefer to  
understand  
why things don’t work than to wonder why they did work…

```
What was happening is this situation, here:

```

if false  
variable = true  
end

if variable  
#do something  
end

```
To my surprise, this is okay! Even though the code in the first

```

if-clause doesn’t get run, the variable in the clause gets created,  
anyway…  
Now, I’m pretty sure this is expected behaviour. What I’m wondering  
is  
how people feel about this. This behaviour makes me feel uneasy. If  
I’m  
using a variable that hasn’t been deliberately created then I’d rather  
have  
the interpreter complain that I haven’t created the variable, as  
planned,  
than to be confused as to why my variable is nil.  
I’m very interested to hear other opinions on the subect. Anyone  
care  
to comment?  
Thank you…

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 23, 2007, 1:20am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/2 "2007-09-23T01:20:54Z")

</div>

Just Another Victim wrote:

> if false  
> variable = true  
> end
> 
> if variable  
> #do something  
> end
> 
> ```
> To my surprise, this is okay!  
> 
> ```

What do you mean by “okay”? Does the following not work as you would  
expect:

if false  
x = 10  
end

if x  
puts “yep”  
else  
puts “nope”  
end

Also, see here:

[http://www.ruby-forum.com/topic/124638#new](http://www.ruby-forum.com/topic/124638#new)

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 23, 2007, 1:23am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/3 "2007-09-23T01:23:20Z")

</div>

7stud – wrote:

> What do you mean by “okay”?

Ok, I see:

> This behaviour makes me feel uneasy. If  
> I’m  
> using a variable that hasn’t been deliberately created then I’d rather  
> have  
> the interpreter complain that I haven’t created the variable, as  
> planned,  
> than to be confused as to why my variable is nil.

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 23, 2007, 1:36am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/4 "2007-09-23T01:36:01Z")

</div>

7stud – wrote:

> Does the following not work as you would  
> expect:
> 
> if false  
> x = 10  
> end
> 
> if x  
> puts “yep”  
> else  
> puts “nope”  
> end

Ah. I see what you are concerned about:

if y  
puts “yep”  
else  
puts “nope”  
end

undefined local variable or method `y’ for main:Object (NameError)

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 23, 2007, 5:20am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/5 "2007-09-23T05:20:39Z")

</div>

On Sep 22, 4:32 pm, “Just Another Victim of the Ambient M.”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> if variable  
> than to be confused as to why my variable is nil.  
> I’m very interested to hear other opinions on the subect. Anyone care  
> to comment?  
> Thank you…

I understand the behavior, and I’ve learned to live with it. But (as  
I’ve noted on numerous occassions) I really don’t like the reverse  
side effect, that you can’t write:  
p foo if foo=true  
even though you can write:  
if foo=true then p foo; end

That two statements that are semantically identical should result in  
different behavior when foo has not previously been assigned a value  
is an unfortunate side effect/tradeoff of the implementation details  
and choices.

I accept it in the same way I accept that arrays and hashes have, in  
some cases, traded purity for speed. It ain’t perfect, but it’s what  
we got.

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 24, 2007, 4:10am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/6 "2007-09-24T04:10:32Z")

</div>

“Phrogz” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

> is an unfortunate side effect/tradeoff of the implementation details  
> and choices.
> 
> I accept it in the same way I accept that arrays and hashes have, in  
> some cases, traded purity for speed. It ain’t perfect, but it’s what  
> we got.

```
I'm interested in to what you're referring, here. How was purity of

```

arrays and hashes compromised for speed?  
Thank you…

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 24, 2007, 5:02am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/7 "2007-09-24T05:02:36Z")

</div>

On Sep 23, 8:05 pm, “Just Another Victim of the Ambient M.”  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> “Phrogz” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message
> 
> > I accept it in the same way I accept that arrays and hashes have, in  
> > some cases, traded purity for speed. It ain’t perfect, but it’s what  
> > we got.
> 
> ```
> I'm interested in to what you're referring, here. How was purity of
> 
> ```
> 
> arrays and hashes compromised for speed?

Things like the fact that Hash and Array literals don’t call their  
#initialize method, or that all Array methods that fetch values from  
the array don’t fall back on a single method that one can intercept or  
override.

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [September 24, 2007, 4:05am UTC](https://www.ruby-forum.com/t/weird-variable-scope-behaviour/115276/8 "2007-09-24T04:05:32Z")

</div>

“7stud --” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in message  
news:removed\_email\_address@domain.invalid…

> > ```
> > puts "yep"
> > 
> > ```
> 
> puts “nope”  
> end
> 
> undefined local variable or method `y’ for main:Object (NameError)

```
I'm not sure, exactly, what I'm concerned about but I can give you 

```

some  
clues.  
It’s a little weird that the above code with variable y results in a  
name error but the previous example with variable x simply results in a  
nil  
object reference. It seems as if they should both result in a nil  
object  
reference or they should both result in a name error, rather than being  
inconsistent with each other.  
The most pragmatic example of a problem, that I can think of, is a  
situation where you have a bug that’s immediately caused by a variable  
that’s unexpectedly nil. Now, you have to trace back the life of the  
variable, which can traverse many different scopes, to hopefully  
discover  
that there was an execution path that didn’t initialize the variable.  
Instead, wouldn’t it have been nice if the interpreter simply told you,  
at  
the variable’s first use, that it didn’t exist 'cause it wasn’t  
initialized?  
Now that I put it this way, I think I see how its current behaviour  
is  
an implementation detail, done for increasing speed, leaking through the  
interface…
