In "Is it possible to sort a list of objects depending on if the individual object's response to a method?", I discovered that the flying saucer doesn't work on booleans.
Consider:
Ruby 1.8.7:
[true, false].sort # => undefined method `<=>' for true:TrueClass (NoMethodError)
true <=> false # => undefined method `<=>' for true:TrueClass (NoMethodError)
Ruby 1.9.3:
[true, false].sort # => comparison of TrueClass with false failed (ArgumentError)
true <=> false # => nil
true <=> true # => 0
false <=> true # => nil
It may have something to do with true and false not having a canonical sort order, because which comes first? But, that sounds pretty weak to me.
Is this a bug in sort
?
<=>
but violate the expectation (implicit contract) that <=> returns a value suitable forsort
. – Urban<=>
was added toObject
("Returns 0 if obj === other, otherwise nil.") and it's that implementation that's confusingsort
. – Urban<=>
should always return0
,-1
, or1
, or be undefined. Returningnil
is violationg the expectation. I agree. – Ragtimenil
is the designers' implementation for 'undefined' (similar to NULL). The alternative would be to throw an exception - perhaps there are scenarios where returning a legitimate value would be preferred to forcing the developer to catch the exception... – Breastfeed<=>
are-1
,0
,1
andnil
for less-than, equal, greater-than and not-comparable. That's the standard protocol for<=>
, and I don't see how the implementation for booleans violates that protocol.true
is equal totrue
, but it is not comparable tofalse
. – Manganesetrue <=> true
being0
strange. I felt uncomparable things returningnil
to violate expectations that we had during 1.8, but now, it changed in 1.9, and that may be another way of thinking. – Ragtimesort
is saying is "hey doofus, true and false are not comparable; try sorting some objects that implement the Comparable module instead" but it comes out "comparison of TrueClass with false failed" which is not nearly as helpful. – Urban