Feature #12134
openComparison between `true` and `false`
Description
There are some needs to sort elements depending on whether they satisfy certain condition expressed as a predicate. For example, to place prime numbers before others:
require "prime"
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| Prime.prime?(e) ? 0 : 1} # => [7, 5, 3, 2, 6, 4, 1]
or to do such sort with the secondary condition to sort by the size:
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| [Prime.prime?(e) ? 0 : 1, e]} # => [2, 3, 5, 7, 1, 4, 6]
Here, the temporal assignment of magic numbers 0
and 1
is ad hoc, but ordering between true
and false
makes sense. And given that there are if
construction (which is unmarked case compared to the unless
construction) and the ternary operator, in which the truthy branch is placed before the falsy branch, I think it makes sense to assume an inherent ordering of true
being placed before false
.
So I propose comparison between true
and false
:
true <=> false # => -1
false <=> true # => 1
Using this, the cases above can be written more directly as:
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| Prime.prime?(e)} # => [7, 5, 3, 2, 6, 4, 1]
[7, 6, 5, 4, 3, 2, 1].sort_by{|e| [Prime.prime?(e), e]} # => [2, 3, 5, 7, 1, 4, 6]
Please do not confuse this with the common proposal to map booleans to integers, particularly true.to_i # => 1
and false.to_i # => 0
. That is arbitrary, and does not make sense. In fact, my proposal goes against such proposal (under the proposal to map booleans, true.to_i <=> false.to_i
translates to 1 <=> 0 # => 1
, which goes against my proposal true <=> false # => 01
).