# Case/when question

**URL:** <https://rubytalk.org/t/case-when-question/25343>\
**Category:** ruby-talk\
**Created:** [1 March 2006 21:13 UTC](https://rubytalk.org/t/case-when-question/25343 "2006-03-01T21:13:16Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chuck\_Remes](https://avatars.discourse-cdn.com/v4/letter/c/3be4f8/32.png) [@Chuck\_Remes](https://rubytalk.org/u/Chuck_Remes)\
**Post date:** [1 March 2006 21:13 UTC](https://rubytalk.org/t/case-when-question/25343/1 "2006-03-01T21:13:16Z")

</div>

I was intrigued by the post that \_why put up a few days/weeks ago about using case/when for testing arrays [1]. I thought I'd give it a try but I can't make it work. What am I doing wrong?

irb(main):001:0\> r1 = (0..12).to\_a  
=\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  
irb(main):002:0\> r2 = (20..32).to\_a  
=\> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]  
irb(main):003:0\> def foo range  
irb(main):004:1\> case range  
irb(main):005:2\> when \*r1  
irb(main):006:2\> puts "#{range} in r1"  
irb(main):007:2\> when \*r2  
irb(main):008:2\> puts "#{range} in r2"  
irb(main):009:2\> else  
irb(main):010:2\* puts "#{range} NOT in any range"  
irb(main):011:2\> end  
irb(main):012:1\> end  
=\> nil  
irb(main):013:0\> foo 3  
NameError: undefined local variable or method `r1' for main:Object  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5:in `foo'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13

This is under OSX:  
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.4.0]

[1] [http://redhanded.hobix.com/bits/wonderOfTheWhenBeFlat.html](http://redhanded.hobix.com/bits/wonderOfTheWhenBeFlat.html)

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [1 March 2006 21:18 UTC](https://rubytalk.org/t/case-when-question/25343/2 "2006-03-01T21:18:45Z")

</div>

Method definitions, unlike blocks, are not closures and do not have access to local variables from the scope where they are defined. Move the vars inside the method, or switch them to instance (or global) vars and it will work.

Hope that helps.

James Edward Gray II

> **···**
>
> On Mar 1, 2006, at 3:13 PM, cremes.devlist@mac.com wrote:
> 
> > I was intrigued by the post that \_why put up a few days/weeks ago about using case/when for testing arrays [1]. I thought I'd give it a try but I can't make it work. What am I doing wrong?
> > 
> > irb(main):001:0\> r1 = (0..12).to\_a  
> > =\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  
> > irb(main):002:0\> r2 = (20..32).to\_a  
> > =\> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]  
> > irb(main):003:0\> def foo range  
> > irb(main):004:1\> case range  
> > irb(main):005:2\> when \*r1  
> > irb(main):006:2\> puts "#{range} in r1"  
> > irb(main):007:2\> when \*r2  
> > irb(main):008:2\> puts "#{range} in r2"  
> > irb(main):009:2\> else  
> > irb(main):010:2\* puts "#{range} NOT in any range"  
> > irb(main):011:2\> end  
> > irb(main):012:1\> end  
> > =\> nil  
> > irb(main):013:0\> foo 3  
> > NameError: undefined local variable or method `r1' for main:Object  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5:in `foo'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13

---

<div class="post-metadata">

**Author:** ![Chuck\_Remes](https://avatars.discourse-cdn.com/v4/letter/c/3be4f8/32.png) [@Chuck\_Remes](https://rubytalk.org/u/Chuck_Remes)\
**Post date:** [1 March 2006 21:20 UTC](https://rubytalk.org/t/case-when-question/25343/3 "2006-03-01T21:20:57Z")

</div>

Responding to my own email...

I figured it out about 5 minutes after sending. This is purely a scope mistake on my part. Variables r1 and r2 are NOT in scope inside foo which is exactly what ruby told me.

The fix is to make r1 and r2 into class vars. Change r1 to @r1 and r2 to @r2 in that example and it works just fine.

Nuby making lots of mistakes!

> **···**
>
> On Mar 1, 2006, at 3:13 PM, cremes.devlist@mac.com wrote:
> 
> > I was intrigued by the post that \_why put up a few days/weeks ago about using case/when for testing arrays [1]. I thought I'd give it a try but I can't make it work. What am I doing wrong?
> > 
> > irb(main):001:0\> r1 = (0..12).to\_a  
> > =\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  
> > irb(main):002:0\> r2 = (20..32).to\_a  
> > =\> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]  
> > irb(main):003:0\> def foo range  
> > irb(main):004:1\> case range  
> > irb(main):005:2\> when \*r1  
> > irb(main):006:2\> puts "#{range} in r1"  
> > irb(main):007:2\> when \*r2  
> > irb(main):008:2\> puts "#{range} in r2"  
> > irb(main):009:2\> else  
> > irb(main):010:2\* puts "#{range} NOT in any range"  
> > irb(main):011:2\> end  
> > irb(main):012:1\> end  
> > =\> nil  
> > irb(main):013:0\> foo 3  
> > NameError: undefined local variable or method `r1' for main:Object  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5:in `foo'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [1 March 2006 21:22 UTC](https://rubytalk.org/t/case-when-question/25343/4 "2006-03-01T21:22:08Z")

</div>

Hi --

> I was intrigued by the post that \_why put up a few days/weeks ago about using case/when for testing arrays [1]. I thought I'd give it a try but I can't make it work. What am I doing wrong?
> 
> irb(main):001:0\> r1 = (0..12).to\_a  
> =\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  
> irb(main):002:0\> r2 = (20..32).to\_a  
> =\> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]  
> irb(main):003:0\> def foo range  
> irb(main):004:1\> case range  
> irb(main):005:2\> when \*r1  
> irb(main):006:2\> puts "#{range} in r1"  
> irb(main):007:2\> when \*r2  
> irb(main):008:2\> puts "#{range} in r2"  
> irb(main):009:2\> else  
> irb(main):010:2\* puts "#{range} NOT in any range"  
> irb(main):011:2\> end  
> irb(main):012:1\> end  
> =\> nil  
> irb(main):013:0\> foo 3  
> NameError: undefined local variable or method `r1' for main:Object  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5:in `foo'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13

You've defined r1 and r2 outside of the scope of the method definition  
block. You need:

&nbsp;&nbsp;&nbsp;def foo(range)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r1 = (0..12).to\_a  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r2 = .... etc

By the way you can also just use the ranges to test inclusion.

David

> **···**
>
> On Thu, 2 Mar 2006, cremes.devlist@mac.com wrote:
> 
> --  
> David A. Black (dblack@wobblini.net)  
> Ruby Power and Light ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))
> 
> "Ruby for Rails" chapters now available  
> from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [1 March 2006 21:25 UTC](https://rubytalk.org/t/case-when-question/25343/5 "2006-03-01T21:25:49Z")

</div>

Hi --

> > I was intrigued by the post that \_why put up a few days/weeks ago about using case/when for testing arrays [1]. I thought I'd give it a try but I can't make it work. What am I doing wrong?
> > 
> > irb(main):001:0\> r1 = (0..12).to\_a  
> > =\> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]  
> > irb(main):002:0\> r2 = (20..32).to\_a  
> > =\> [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]  
> > irb(main):003:0\> def foo range  
> > irb(main):004:1\> case range  
> > irb(main):005:2\> when \*r1  
> > irb(main):006:2\> puts "#{range} in r1"  
> > irb(main):007:2\> when \*r2  
> > irb(main):008:2\> puts "#{range} in r2"  
> > irb(main):009:2\> else  
> > irb(main):010:2\* puts "#{range} NOT in any range"  
> > irb(main):011:2\> end  
> > irb(main):012:1\> end  
> > =\> nil  
> > irb(main):013:0\> foo 3  
> > NameError: undefined local variable or method `r1' for main:Object  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5:in `foo'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):13
> 
> Responding to my own email...
> 
> I figured it out about 5 minutes after sending. This is purely a scope mistake on my part. Variables r1 and r2 are NOT in scope inside foo which is exactly what ruby told me.
> 
> The fix is to make r1 and r2 into class vars. Change r1 to @r1 and r2 to @r2 in that example and it works just fine.

Sort of 🙂 Actually @r1 is an instance variable, not a class  
variable. It's true that if you do:

&nbsp;&nbsp;&nbsp;@a = 1  
&nbsp;&nbsp;&nbsp;def meth  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts @a  
&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;meth

you'll get "1", but only if you are writing code at the top level of  
the program. If you do this:

&nbsp;&nbsp;&nbsp;class MyClass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@a = 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def meth  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts @a  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;MyClass.new.meth

you won't because, the two @a's are different from each other.

Class variables (@@r1) will cross the method-definition divide, but  
they're somewhat cumbersome.... The best thing is to create local  
variables in the scope where you need them (the method definition).

David

> **···**
>
> On Thu, 2 Mar 2006, cremes.devlist@mac.com wrote:
> 
> > On Mar 1, 2006, at 3:13 PM, cremes.devlist@mac.com wrote:
> 
> --  
> David A. Black (dblack@wobblini.net)  
> Ruby Power and Light ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))
> 
> "Ruby for Rails" chapters now available  
> from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)
