[ruby-core:77782] [Ruby trunk Bug#12875] Fixnum bit operator and coerce

From: lionel.perrin@...
Date: 2016-10-27 14:10:14 UTC
List: ruby-core #77782
Issue #12875 has been updated by Lionel PERRIN.

Description updated

----------------------------------------
Bug #12875: Fixnum bit operator and coerce
https://bugs.ruby-lang.org/issues/12875#change-61086

* Author: Lionel PERRIN
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32]
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
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



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next