Project

General

Profile

Bug #14437

Updated by nobu (Nobuyoshi Nakada) about 6 years ago

Here's extracted test sample: 

 ~~~ruby ~~~ 
 class Item 
   def initialize(value) 
     @value = value 
   end 

   def coerce(other) 
     [Item.new(other), self] 
   end 

   def ==(other) 
     Item.new("#{inspect} == #{other.inspect}") 
   end 

   def !=(other) 
     Item.new("#{inspect} != #{other.inspect}") 
   end 

   def inspect 
     "(#{@value})" 
   end 
 end 

 a = Item.new("a") 
 p [RUBY_VERSION, 42 == a, 42 != a, a == 42, a == a, a != 42, a != a] 
 ~~~ 

 I'd expect it to print: `["2.x.x", ((a) == 42), ((a) != 42), ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))]` 

 What happens instead is: 

 ~~~ 
 ["1.9.3", ((a) == 42), false, ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))] 
 ["2.2.0", ((a) == 42), false, ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))] 
 ["2.3.3", ((a) == 42), false, ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))] 
 ["2.4.1", true, false, ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))] 
 ["2.5.0", true, false, ((a) == 42), ((a) == (a)), ((a) != 42), ((a) != (a))] 
 ~~~ 

 So != never used coerce, and now == doesn't use coerce either. 
 Using Bignum value instead of 42 in this example breaks it even pre-2.4. 

 So, the question is: 
 * is using coerce like this not supported, and it was just an accident that it used to work? (and I should redefine Integer#== and Integer#!=) 
 * or is it meant to work, and it's a ruby bug? 

 For context, it's a problem for z3 gem, which builds big mathematical expressions like Z3.Int("a")+Z3.Int("b") == 4 
 and then uses Microsoft Z3 solver to solve them. Not being able to use == / != because of this issue would really reduce its usability. 

 Using coerce this way works just fine with +, -, *, >=, etc., it's just == and != which don't work.

Back