# Why is my var undefined?

**URL:** <https://www.ruby-forum.com/t/why-is-my-var-undefined/127949>\
**Category:** Ruby\
**Created:** [February 3, 2008, 1:10am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949 "2008-02-03T01:10:38Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 1:10am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/1 "2008-02-03T01:10:38Z")

</div>

I’m new to ruby and I have the following code:

index=0  
unsorted\_array.each do |value|  
if index==0  
smallest=value  
smallest\_index=0  
elsif value\<smallest  
smallest=value  
smallest\_index=index  
end  
index=index+1  
end

When it gets to index 1, it crashes and says that smallest is  
undefined (on the elsif line). Why is that, when it gets defined in  
the first pass (index = 0) ?

Thanks for helping a newbie out.

Tim

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 1:27am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/2 "2008-02-03T01:27:07Z")

</div>

Tim wrote:

> I’m new to ruby and I have the following code:
> 
> index=0  
> unsorted\_array.each do |value|  
> if index==0  
> smallest=value  
> smallest\_index=0  
> elsif value\<smallest  
> smallest=value  
> smallest\_index=index  
> end  
> index=index+1  
> end
> 
> When it gets to index 1, it crashes and says that smallest is  
> undefined (on the elsif line). Why is that, when it gets defined in  
> the first pass (index = 0) ?
> 
> Thanks for helping a newbie out.
> 
> Tim

It’s only defined for the scope that it’s in… which is the “if” block…  
Once it leaves that block and your code returns to the  
“unsorted\_array.each” scope, “smallest” is out of scope and therefore no  
longer defined.

Dave T. has a free online version of Ruby 1.6 referred as the Pick  
Axe book which discusses scope and I think you will find it very useful

hth

ilan

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 6:06am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/3 "2008-02-03T06:06:04Z")

</div>

On Feb 2, 2008 6:09 PM, Tim [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m new to ruby and I have the following code:
> 
> index=0

you could insert “smallest = nil” here

> When it gets to index 1, it crashes and says that smallest is  
> undefined (on the elsif line). Why is that, when it gets defined in  
> the first pass (index = 0) ?

Not sure what you are trying to do, but if your data is not unique…

a = 5,1,4,7,2,1,9,2,1  
smallest = a.min  
s\_indexes = []  
a.each\_with\_index {|v, i| s\_indexes \<\< i if v == a.min}

If you don’t want to do it that way, then…

a = 5,1,4,7,2,1,9,2,1  
smallest, s\_indexes = a.first, []  
a.inject(a.first) {|m, e| e \< m ? e : m}  
a.each\_with\_index {|v, i| s\_indexes \<\< i if v == a.min}

Todd

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 10:02am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/4 "2008-02-03T10:02:37Z")

</div>

Todd B. wrote:

> On Feb 2, 2008 11:05 PM, Todd B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > a.inject(a.first) {|m, e| e \< m ? e : m}  
> > a.each\_with\_index {|v, i| s\_indexes \<\< i if v == a.min}
> 
> Sorry, these lines are supposed to be…
> 
> smallest = a.inject(a.first) {|m, e| e \< m ? e : m}  
> a.each\_with\_index {|v, i| s\_indexes \<\< i if v \<= smallest}
> 
> Todd

ï»¿In Ruby 1.9, finding indexes of all elements which have minimal value  
is easily done using a new iterator chaining feature:

a = 5, 1, 4, 7, 2, 1, 9, 2, 1

min\_value = a.min

a.each\_with\_index.inject([]){|accum, (elem, index)|

elem == min\_value ? accum \<\< index : accum

}

Output:

=\> [1, 5, 8]

Best regards  
Isidor Nikolic

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 6:14am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/5 "2008-02-03T06:14:51Z")

</div>

On Feb 2, 2008 11:05 PM, Todd B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> a.inject(a.first) {|m, e| e \< m ? e : m}  
> a.each\_with\_index {|v, i| s\_indexes \<\< i if v == a.min}

Sorry, these lines are supposed to be…

smallest = a.inject(a.first) {|m, e| e \< m ? e : m}  
a.each\_with\_index {|v, i| s\_indexes \<\< i if v \<= smallest}

Todd

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 12:33pm UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/6 "2008-02-03T12:33:46Z")

</div>

Ilan B. wrote:

> It’s only defined for the scope that it’s in… which is the “if” block

It’s not local to the if-block. It’s local to each execution of the  
each-  
block.

HTH,  
Sebastian

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 1:02pm UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/7 "2008-02-03T13:02:07Z")

</div>

On Feb 3, 2008 11:50 AM, Eivind E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The variable is not “pass”-based - it is “scope” based, ie, it only  
> exists inside a particular _lexical_ - that is, textual - part of your  
> program (in this case, your if statement, NOT the loop).

This was slightly clumsily written; the variable leak through to the  
end of the block, but isn’t present for the entire loop. Sebastians  
description is correct.

Eivind.

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 11:51am UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/8 "2008-02-03T11:51:48Z")

</div>

On Feb 3, 2008 1:09 AM, Tim [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m new to ruby and I have the following code:

Add  
smallest = nil  
smallest\_index = 0  
here, and your code will work.

> end
> 
> When it gets to index 1, it crashes and says that smallest is  
> undefined (on the elsif line). Why is that, when it gets defined in  
> the first pass (index = 0) ?

The variable is not “pass”-based - it is “scope” based, ie, it only  
exists inside a particular _lexical_ - that is, textual - part of your  
program (in this case, your if statement, NOT the loop). In other  
words, you get a new variable for each pass through the loop.

By adding the initialization, you get th same variable all loop  
iterations.

Here is another variant of your code that uses essensially the same  
algorithm and simplifies the code a bit:

smallest\_index = 0  
smallest\_value = nil  
unsorted\_array.each\_with\_index do |value, index|  
if !smallest\_value || value\<smallest  
smallest=value  
smallest\_index=index  
end  
end

Eivind.

---

<div class="post-metadata">

**Author:** ![tim](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ce73a5/32.png) [@tim](https://www.ruby-forum.com/u/tim)\
**Post date:** [February 3, 2008, 6:30pm UTC](https://www.ruby-forum.com/t/why-is-my-var-undefined/127949/9 "2008-02-03T18:30:31Z")

</div>

Thanks to all for the help. I take it from the comments here that any  
variables which are defined in an iteration block (or a Proc)are local  
to each iteration. Thinking about it, that makes sense because each  
iteration requires its own call from each (or each\_with\_index,  
etc.)…with the variables being treated somewhat like method  
variables.
