I became curious when this didn't work as I expected:
var = "foo"
case var.class
when String
puts "bar"
else
puts "baz"
=> "baz"
I understand that the case statement is using ===, but I don't understand what === does. The docs say...
Case Equality – For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.
http://ruby-doc.org/core-2.2.3/Object.html#method-i-3D-3D-3D
Does this mean that === in Class (or one of its modules) overrides === in Object? I'm confused.
=== is overridden for Class objects (and more generally, Module objects) to mean "is the right-hand side an instance of the left-hand side".
For instance:
>> String === ""
=> true
>> Class === String
=> true
This is unintuitive, but it's true. It does, however, make what you're trying to do even shorter:
var = "foo"
case var
when String
puts "bar"
else
puts "baz"
end
# outputs "bar", since String === "foo"
Here's why your attempt didn't work: Ruby evaluates String === String, which is false, since the String class is not itself a string.
You are dealing with case equality here. Here, it is overridden by descendants to provide meaningful semantics. In this case, Module overrides it.
Case Equality — Returns true if an object is an instance of a module or one of the module's descendants. Of limited use for modules, but can be used in case statements to classify objects by class.
In modules, === acts like Ruby's is_a? method.
In your case, it returns false because "Foo".class isn't an instance of the string class.
"Foo".class.is_a?(String)
=> false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With