14

What is the best way to use a class object in case statement? Suppose I have a which is an instance of the Class class. I want to match it against different classes. If I do

case a
when String then ...
when Fixnum then ...
end

this will not give the intended result because even if a == String for example, a === String is not true. What is the clever way to do this?

sawa
  • 165,429
  • 45
  • 277
  • 381
  • 1
    same topic [here](http://stackoverflow.com/questions/3908380/ruby-class-types-and-case-statements) – Selman Ulug Mar 02 '12 at 18:04
  • 2
    @selman The question you linked is irrelevant. The `item` in that example is not a class instance. – sawa Mar 02 '12 at 18:08

4 Answers4

16

I wouldn't use to_s, because "String".to_s would be "String", so maybe I'd do

case
when a == String then ...
when a == Fixnum then ...
end

or

a = String

case [a]
when [String] then puts "String"
when [Array] then puts "Array"
end
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • 1
    I don't get why the `[]` trick works. It pretty much does exactly what I want it to. Could you give any pointers? – wrtsprt Oct 25 '17 at 09:21
  • 1
    @wrtsprt because Array doesn't override the Case Equality operator :) So this is the same as `[String] == [String]` https://stackoverflow.com/questions/7734245/why-doesnt-array-override-the-triple-equal-sign-method-in-ruby – dentarg Apr 27 '20 at 11:41
11

The problem with using something like this:

case a.to_s
when "String" then ...
when "Fixnum" then ...
end

is that it completely misses subclasses so you can get something that is a String but is missed by your first branch. Also, name would be a better choice than to_s since semantically, you're testing the class's name rather than its string representation; the result may be the same but case a.name would be clearer.

If you want to use a case and deal with subclassing then you could use Module#<= like this:

case
when a <= String then ...
when a <= Fixnum then ...
end

Yes, you have to repeat a in each when but that's just how case works.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
-1

Because

Array === Array # return false

and "case when" means "===", so you meet the problem.

Lane
  • 4,682
  • 1
  • 36
  • 20
-1

My temporary answer is to use to_s, but am not sure if this is the best that can be done. Waiting for better answers.

case a.to_s
when "String" then ...
when "Fixnum" then ...
end
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
sawa
  • 165,429
  • 45
  • 277
  • 381