Project

General

Profile

Bug #12875

Updated by lionel_perrin (Lionel PERRIN) over 7 years ago

The following code raises "Test can't be coerced into Fixnum (TypeError)" 

 ~~~ ruby 
 class Test 
   attr_accessor :value 
   def initialize(value) 
     @value = value 
   end 
   def |(other) 
     case(other) 
     when Test 
       @value | other.value 
     else 
       @value | other 
     end 
   end 
   def coerce(other) 
     [Test.new(other), self] 
   end 
 end 

 1 | Test.new(2) 
 ~~~ 

 whereas the following works fine 

 ~~~ ruby 
 class Test 
   attr_accessor :value 
   def initialize(value) 
     @value = value 
   end 
   def +(other) 
     case(other) 
     when Test 
       @value + other.value 
     else 
       @value + other 
     end 
   end 
   def coerce(other) 
     [Test.new(other), self] 
   end 
 end 

 1 + Test.new(2) 
 ~~~ 

 It looks to me that the implementation of bit_coerce in numeric.c is not correct: 

 
 ~~~ c 
 static int 
 bit_coerce(VALUE *x, VALUE *y) 
 { 
     if (!RB_INTEGER_TYPE_P(*y)) { 
	 VALUE orig = *x; 
	 do_coerce(x, y, TRUE); 
	 if (!RB_INTEGER_TYPE_P(*x) && !RB_INTEGER_TYPE_P(*y)) { 
	     coerce_failed(orig, *y); 
	 } 
     } 
     return TRUE; 
 } 
 ~~~ 

 My feeling is that it should be fine for the coerce method to return something else than integers, as long as the bit operator is implemented on the first element of the array. 
 For instance, in my case, it returns two Test instances and the operator '|' is correctly defined on Test instances. It should try this operator. 

 Regards, 

 Lionel

Back