Identifying Classes with case Control Structure
TIL
I wanted to use Ruby’s case/when
control structure to identify the class of a specific object, then do something to
the object based on that. My solution went something like this:
def identify_class(obj)
case obj.class
when Car, Truck, Bus
puts "It's a vehicle"
when Apple, Orange, Grape
puts "It's a fruit"
else
puts "I don't know what to do with this!"
end
end
identify_class(Car.new) # => I don't know what to do with this!"
identify_class(Apple.new) # => I don't know what to do with this!"
Not the result I was expecting…
After some digging, I came across a Stack Overflow Q/A that shed some light on the issue; internally, case
calls
===
on the object we’re evaluating against. If we fire up a ruby console, it’s easy to see that Array === Array
yields false
while Array === Array.new
returns true
🙂. If we remove the call to #class
in our case statement,
this solves our problem:
def identify_class(obj)
case obj
when Car, Truck, Bus
puts "It's a vehicle"
when Apple, Orange, Grape
puts "It's a fruit"
else
puts "I don't know what to do with this!"
end
end
identify_class(Car.new) # => It's a vehicle
identify_class(Apple.new) # => It's a fruit