Ruby Case Statement comparison ... a feature, not a bug :)
By: Johnathon Wright on: November 26, 2008
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'
---ruby case Integer when Integer 'success' else 'failure'
whereas this code results in 'success'
---ruby case 3 when Integer 'success' else 'failure'
Ruby uses the === operator for "case-statement equality":http://www.pluitsolutions.com/2006/10/09/comparing-equality-eql-equal-and-case-equality-in-ruby/ . 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.
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
UPDATE: An "exception to this rule":http://blog.mustmodify.com/2009/05/1day-rubys-case-operator-behaved-badly.html :
Fixnum === 3.days=> false