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