Determine type of class

Because it was just doing string comparisons and not working with the actual types. I.e. given the setup of like:

class A; end
class B < A; end
class C < B; end

The case was expanding to like, assuming we’re using C again like your first example:

tmp = obj.class.to_s # => "C"
if tmp == "A"
  puts 0
elsif tmp == "B"
  puts 1
elsif tmp == "C"
  puts 2
end

In this case, even if C is a child of A and B, it wasn’t matching, as again its just string comparisons, so it doesn’t match anything until it gets to "C", and prints 2. However when you switched to the actual typed version, the semantics of the resulting if statement changed to something like:

tmp = obj
if tmp.is_a? A
  puts 0
elsif tmp.is_a? B
  puts 1
elsif tmp.is_a? C
  puts 2
end

Notice == is now is_a? which takes into consideration that C is a child of A and B, which results in a 0 being printed. This is because of crystal/src/class.cr at eb46097440bf20d22eff6c38fc82732927bb193e · crystal-lang/crystal · GitHub, since #=== is what is used for case equality.