Bug #12864
closedRegression comparing Integer (Fixnum) to Comparable (2.4.0-preview2)
Description
If you have a class including Comparable
and expecting to be compared to Integer
, equality test doesn't work anymore. This worked in 2.3.1.
Example:
class MyInteger
include Comparable
def initialize(i)
@i = i.to_i
end
attr_reader :i
def <=>(other)
@i <=> (other.is_a?(MyInteger) ? other.i : other)
end
end
[5, 2**62, 2**61].each do |i|
puts MyInteger.new(i) == i
puts i == MyInteger.new(i)
end
Output in 2.3.1 and expected output:
true
true
true
true
true
true
Output in 2.4.0-preview2:
true
false
true
true
true
../test5.rb:16:in `==': invalid inspect_tbl pair_list for :== in #<Thread:0x000000014afaf0 run> (TypeError)
from ../test5.rb:16:in `block in <main>'
from ../test5.rb:14:in `each'
from ../test5.rb:14:in `<main>'
As shown, if the MyInteger
version is the left hand side of ==
, the comparison works as expected.
If the Integer
is on the left hand side, then the problem depends on its size:
- If it is big enough that it is actually a Bignum (
<= -(2**62-1)
or>= 2**62
) then it compares true as expected - If it is a smallish fixnum (between
-(2**61)
and2**61-1
) then it incorrectly compares false - For large fixnums not covered above (eg
2**61
) the comparison raises aTypeError
.
This does NOT affect other Comparable methods. Eg, less than/greater than. 3 < MyInteger.new(4)
works, as long as coerce
is defined. The examples above never try to call coerce.
A workaround is to define ==
on our class. If this is done the above tests all print true:
def MyInteger
def ==(other)
@i == (other.is_a?(MyInteger) ? other.i : other)
end
end
However this shouldn't be necessary since Comparable
is adding an equality method.
Using bisect, I am pretty sure this regression was introduced in r55891.
Updated by nobu (Nobuyoshi Nakada) over 7 years ago
- Status changed from Open to Closed
Applied in changeset r56474.
numeric.c: fix up r55891
- numeric.c (num_funcall1): check recursion by inverse pair, to
fix fake infinite recursion. [ruby-core:77713] [Bug #12864]