Ruby Case Statement comparison ... a feature, not a bug :)
I accidentally discovered an unintuitive aspect of Ruby case statements. I can't decide whether it's a bug or a feature, or both.
This code results in 'failure'
whereas this code results in 'success'
Ruby uses the === operator for case-statement equality . When the left-hand is an instance, then it operates as ==. When the left-hand is an object, then the operator returns true if the right-hand.class.ancestors.include?(left_hand). Here are a few examples of the behavior. The value being tested (3, above) is on the right. The values that cause you to fall in to the case (Integer, above) are on the left.
UPDATE:
An exception to this rule :
This code results in 'failure'
1 2 3 4 5 6 |
case Integer when Integer 'success' else 'failure' end |
whereas this code results in 'success'
1 2 3 4 5 6 |
case 3 when Integer 'success' else 'failure' end |
Ruby uses the === operator for case-statement equality . When the left-hand is an instance, then it operates as ==. When the left-hand is an object, then the operator returns true if the right-hand.class.ancestors.include?(left_hand). Here are a few examples of the behavior. The value being tested (3, above) is on the right. The values that cause you to fall in to the case (Integer, above) are on the left.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
>> # These two instances are equal >> 'hello' === 'hello' => true >> # When the left-hand operand is a Class, then we test whether the right side >> # is an instance of this class or one of its ancestors, rather than for equality. >> String === 'hello' => true >> # String is an instance of Object. >> Object === String >> true >> # however, String is not an instance of a String or any of its ancestors. >> String === String => false >> # That operand also handles other magical behaviors of case statements, such as ranges: >> (1..10) === 4 => true >> (1..10) === 20 => false |
UPDATE:
An exception to this rule :
1 |
>> Fixnum === 3.days=> false |