Forum: Ruby Confusion with Ruby's "case/when" block statement

Posted by Kumar R. (kumar_r)
on 2013-03-03 21:50
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.
Posted by Hans Mackowiak (hanmac)
on 2013-03-03 22:14
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
Posted by D. Deryl Downey (ddd)
on 2013-03-03 22:19
(Received via mailing list)
Dude, read a bit. http://phrogz.net/ProgrammingRuby/language.html under
Operator Expressions. And read the source of the method being called.

Duh
Posted by D. Deryl Downey (ddd)
on 2013-03-03 22:25
(Received via mailing list)
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!
Posted by Kumar R. (kumar_r)
on 2013-03-03 22:58
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
Posted by Kumar R. (kumar_r)
on 2013-03-03 23:22
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 ?
Posted by Henry Maddocks (Guest)
on 2013-03-04 01:31
(Received via mailing list)
On 4/03/2013, at 11:22 AM, "Kumar R." <lists@ruby-forum.com> 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
Posted by Kumar R. (kumar_r)
on 2013-03-04 18:41
Actually the below paragraph made me confused: from the link :
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.
Posted by Robert Klemme (robert_k78)
on 2013-03-05 15:42
(Received via mailing list)
On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. <lists@ruby-forum.com> 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
Posted by Kumar R. (kumar_r)
on 2013-03-05 19:16
Robert Klemme wrote in post #1100204:
> On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. <lists@ruby-forum.com> 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.
Posted by Robert Klemme (robert_k78)
on 2013-03-05 19:46
(Received via mailing list)
On Tue, Mar 5, 2013 at 7:16 PM, Kumar R. <lists@ruby-forum.com> wrote:
> Robert Klemme wrote in post #1100204:
>> On Mon, Mar 4, 2013 at 6:41 PM, Kumar R. <lists@ruby-forum.com> 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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.