On Tuesday 06 July 2010, Pieter H. wrote:
Because that uses
1 === Fixnum
that is it calls the === method of 1, rather than the === method of
Fixnum#=== works like Fixnum#== (note here we’re speaking of the ===
method of Fixnum, as shown by the use of the # symbol, rather than of
class method I spoke of in my other message and which is indicated using
symbol), so 1 === Fixnum returns false because Fixnum is not a number
can’t be equal to 1.
|Furthermore, In my original example, one would expect a.class === Fixnum
|to return true in any case, as ‘===’ is supposed to be more forgiving
|than ‘==’, but it doesn’t.
You shouldn’t think of === as being more forgiving than ==. According to
documentation of Object#===:
Case Equality–For class Object, effectively the same as calling #==,
typically overridden by descendents to provide meaningful semantics in
This means that === is not a more forgiving version of ==. It’s an
which is written so that it makes things easier in a case statement. For
example, take the class Regexp. Suppose I have a string str and I want
which regexp matches it. I can write:
This can be done because Regexp#=== returns true or false depending on
value returned by its match? method.
The same happens for Ranges. If n is an integer, I can write:
Again, this works as I expect because Range#=== uses the include? method
determine whether to return true or false.
For certain classes, instead, the more sensible behaviour for this
to work like ==. This is what happens with Integer, String and Array,
Now, regarding your case. When you put a class in a When clause, what do
usally want to do? Check whether the object being tested is an instance
that class. So Class#=== returns true if the object is an instance of
class and false if it isn’t. And since Fixnum is not an instance of
you get false.
|This is all a bit counter intuitive to me and !(least surprising).
Once learnt that case statements use the === operator (and I think most
ruby books mention it when they speak of case), I had no issue with
Indeed, I think it’s a simple way to be able to use the case statement
meaningful way also with custom classes (otherwise, you’d be limited to
only with built-in classes, as in C, where you can’t even use it with
I hope what I said clarified things at least a bit.