# Confusion with Ruby's "case/when" block statement

**URL:** <https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083>\
**Category:** Ruby\
**Created:** [March 3, 2013, 9:50pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083 "2013-03-03T21:50:35Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 9:50pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/1 "2013-03-03T21:50:35Z")

</div>

Ruby uses `===` operator on the `case/when` type execution style.Now It  
also known that Ruby depending on the type  
of the thing present in the `when` clause, calls the respective `.===`  
method.

Say `when` statement contains the `class` names, then the rule is - `it will use Module#===, which will return true if the right side is an instance of, or subclass of, the left side.` One example with this context is:

Here `instance of` test occurs

obj = ‘hello’  
#=\> “hello”  
case obj  
when String  
print ‘It is a string’  
when Fixnum  
print ‘It is a number’  
else  
print ‘It is not a string’  
end  
#It is a string  
#=\> nil

Here `subclass of` test occurs

num = 10  
#=\> 10  
case num  
when Numeric  
puts “Right class”  
else  
puts “Wrong class”  
end  
#Right class  
#=\> nil

Now `when` contains `String` literals then String#=== is called, which  
in turn checks if left and right handside  
literal are same(same chracter in same sequence) or not.

a = “abc”  
#=\> “abc”  
case a  
when “def” then p “Hi”  
when “abc” then p “found”  
else “not found”  
end  
#“found”  
#=\> “found”

The all logic is too cool. Now my query is with `case/when` structure -

How does ruby know if `when` holding `class`, or `String` literals or  
anything valid at runtime?

or

What test does it perform before calling the respective `.===` operator.

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 10:14pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/2 "2013-03-03T22:14:28Z")

</div>

nothing … is just calls ===

in your case:  
case num  
when Numeric

it calls Numeric === num which returns true for num = 10

this one works too:

case  
when false  
p “wrong”  
when true  
p “right”  
end  
#=\> “right”

or you can use other formula, it will break if it find something that is  
evaluated into true or when used something in the case statement, wich  
is result === case\_value

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 10:19pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/3 "2013-03-03T22:19:10Z")

</div>

Dude, read a bit. [The Ruby Language](http://phrogz.net/ProgrammingRuby/language.html) under  
Operator Expressions. And read the source of the method being called.

Duh

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 10:58pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/4 "2013-03-03T22:58:58Z")

</div>

Before understanding the `Case/when` working principal,let me clear the  
below which `while` does when it gets its turn.

```
String.===("abc") #=> true

```

Because “abc” is an instance of `String` class. - Am I right?

Now I tried the below just to check who is whose super class.

```
10.class #=> Fixnum
Fixnum.superclass #=> Integer
Integer.superclass #=> Numeric
Numeric.superclass #=> Object

```

Humm. That means the below returns `true` as Fixnum is also the indirect  
subclass of `Numeric`. - Am I right?

```
Numeric.===(10) #=> true

```

But why then the below outputs contradictory to the above?

```
Numeric.===(Fixnum) #=> false

```

One more question is -

when we are calling `Numeric.===(10)` and `String.===("abc")` . I think  
we are sending not `"abc"` and `10` rather `"abc".class` and `10.class`.

I might be 100% wrong, In that case please correct me.

Thanks

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 11:22pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/5 "2013-03-03T23:22:18Z")

</div>

10.===(10) #=\> true  
Numeric.===(10) #=\> true

Now look at the above. Both return `true`. Does they output `true` on  
the same logic? I think `NO`. `10.===(10)` is just like `10 ==(10)`  
comparison. But `Numeric.===(10)` outputs `true` as class of `10` is the  
subclass of `Numeric`.

“abc”.===(“abc”) #=\> true  
String.===(“abc”) #=\> true

Now look at the above. Both return `true`. Does they output `true` on  
the same logic? I think `NO`. `"abc".===("abc")` is just like simple  
string literal comparison `"abc" ==("abc")` comparison. But  
`String.===("abc")` outputs `true` as `"abc"` which is an instance of  
`String`.

Now my question is how ruby detects lefthand side operands types and  
apply the proper rule of comparisons ?

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 4, 2013, 1:31am UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/6 "2013-03-04T01:31:04Z")

</div>

On 4/03/2013, at 11:22 AM, “Kumar R.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Now look at the above. Both return `true`. Does they output `true` on  
> the same logic? I think `NO`. `"abc".===("abc")` is just like simple  
> string literal comparison `"abc" ==("abc")` comparison. But  
> `String.===("abc")` outputs `true` as `"abc"` which is an instance of  
> `String`.
> 
> Now my question is how ruby detects lefthand side operands types and  
> apply the proper rule of comparisons ?

It doesn’t detect anything.You are calling the === method on String, you  
have even written it as such `String.===("abc")`. Each class is free to  
implement it how ever they want.

This is basic OO

Henry

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 3, 2013, 10:25pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/7 "2013-03-03T22:25:36Z")

</div>

As _clearly_ stated (even within ANY ruby language tutorial explaining  
how  
ruby works)

“A case expression searches for a match by starting at the first (top  
left) comparison, performing comparison === target. When a comparison  
returns true, the search stops, and the body associated with the  
comparison is executed. case then returns the value of the last  
expression  
executed. If no comparison matches: if an else clause is present, its  
body  
will be executed; otherwise, case silently returns nil.”

There’s the ‘test’ it performs, AND what method is run _for_ the test,  
AND  
what happens afterwards.

READ IT!

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 5, 2013, 3:42pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/8 "2013-03-05T15:42:29Z")

</div>

On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Module#===) operator, which tests if the right-hand side is\_a? left-hand  
> side. The syntax is simple and elegant.

Now, what do you want to know? Or is everything clear now?

Cheers

robert

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 4, 2013, 6:41pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/9 "2013-03-04T18:41:15Z")

</div>

Actually the below paragraph made me confused: from the link :  
[http://ruby.about.com/od/control/a/The-Case-Statement.htm](http://ruby.about.com/od/control/a/The-Case-Statement.htm)

# What Type?

A common use for the case statement is to determine the type of the  
value and do something different depending on its type. Though this  
breaks Ruby’s customary duck typing, it’s sometimes necessary to get  
things done. This works by using the Class#=== (technically, the  
Module#===) operator, which tests if the right-hand side is\_a? left-hand  
side. The syntax is simple and elegant.

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 5, 2013, 7:16pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/10 "2013-03-05T19:16:07Z")

</div>

Robert K. wrote in post #1100204:

> On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Module#===) operator, which tests if the right-hand side is\_a? left-hand  
> > side. The syntax is simple and elegant.
> 
> Now, what do you want to know? Or is everything clear now?
> 
> Cheers
> 
> robert

@Robert - that `is_a?` test actually made me confused. as `when` test  
for subclass or instance of or any thing valid . But how `is_a` doing  
help to the `while` clause that is my confusion.

---

<div class="post-metadata">

**Author:** ![kumar\_r](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kumar\_r](https://www.ruby-forum.com/u/kumar_r)\
**Post date:** [March 5, 2013, 7:46pm UTC](https://www.ruby-forum.com/t/confusion-with-rubys-case-when-block-statement/227083/11 "2013-03-05T19:46:12Z")

</div>

On Tue, Mar 5, 2013 at 7:16 PM, Kumar R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Robert K. wrote in post #1100204:
> 
> > On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> > 
> > > Module#===) operator, which tests if the right-hand side is\_a? left-hand  
> > > side. The syntax is simple and elegant.
> > 
> > Now, what do you want to know? Or is everything clear now?

> @Robert - that `is_a?` test actually made me confused. as `when` test  
> for subclass or instance of or any thing valid . But how `is_a` doing  
> help to the `while` clause that is my confusion.

Yes, you are confused. We were talking about “case … when” and not  
“while”.

Module#is\_a? and Module#=== implement the same test.

I suggest you get yourself a Ruby tutorial and work through it start  
to end - including all the exercises.

Cheers

robert
