Case when and class

I’ve found in case / when if the case is about a class :

case my_var.class
when String then puts my_var
when Array then my_var.each {|v| puts v}
end

doesn’t work i do have to use :

case my_var.class.to_s
when ‘String’ then puts my_var
when ‘Array’ then my_var.each {|v| puts v}
end

why ?

(with ruby 1.9.x)

when ‘String’ then puts my_var
when ‘Array’ Â then my_var.each {|v| puts v}
end

why ?

“when” condition in case statement uses === to compare objects. For
strings a = b is true if a and b have the same characters, however
String === String is false:

a = “Hello”
=> “Hello”

b = “Hello”
=> “Hello”

a === b
=> true

String === String
=> false

BTW “===” is a method:

a.===(b)
=> true

so you can define your own rules when objects should be considered
equal:

class Marble
attr_accessor :size, :color

def initialize(size, color)
self.size = size
self.color = color
end

def ===(other)
self.color == other.color
end

end

m1 = Marble.new(0.5, “red”)
m2 = Marble.new(0.5, “green”)
m3 = Marble.new(0.7, “red”)

case m1
when m2
puts “Matching marble is m2”
when m3
puts “Matching marble is m3”
else
puts “No match”
end

The result is “Matching marble is m3”

Regards,
Rimantas

2010/6/11 Une Bévue [email protected]:

I’ve found in case / when if the case is about a class :

case my_var.class
when String then puts my_var
when Array then my_var.each {|v| puts v}
end

doesn’t work

case calls the method === on the when object passing the case object
as an argument. So the above is calling:

String.=== (my_var.class)

If you check this:

http://ruby-doc.org/core/classes/Module.html#M001666

it says it returns true if the object is an instance of this class.
So you don’t have to pass the class, but the object itself:

case my_var
when String then puts my_var
when Array then my_var.each {|v| puts v}
end

irb(main):003:0> def test var
irb(main):004:1> case var
irb(main):005:2> when String then puts var
irb(main):006:2> when Array then var.each {|v| puts v}
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> test “hello”
hello
=> nil
irb(main):010:0> test [1,2,3]
1
2
3
=> [1, 2, 3]

i do have to use :

case my_var.class.to_s
when ‘String’ then puts my_var
when ‘Array’ then my_var.each {|v| puts v}
end

You can also do this, but the above is cleaner.

Jesus.

On 2010-06-10 23:41:05 -0700, Une Bévue said:

when ‘String’ then puts my_var
when ‘Array’ then my_var.each {|v| puts v}
end

why ?

(with ruby 1.9.x)

Because of the behavior of the Module #== operator – which you can
look it up at ruby-doc.org – you can somply do this:

case my_var
when String then puts my_var
when Array …
end

On 2010-06-11 00:29:24 -0700, Rein H. said:

look it up at ruby-doc.org – you can somply do this:

case my_var
when String then puts my_var
when Array …
end

Woops, that should be Module#=== of course.

Jesús Gabriel y Galán [email protected] wrote:

You can also do this, but the above is cleaner.

yes of course, clear enough, thanks !

For strings a = b is true if a and b have the same characters

err, I ment a === b . For strings a === b is the same as a == b.
That’s mostly true for other objects too (if they don’t override ===
),
but not always.

Regards,
Rimantas

Rein H. [email protected] wrote:

Woops, that should be Module#=== of course.

ok, well undestood, thanks !