diff --git a/complex.c b/complex.c index 38a1907aac..c4d4f80848 100644 --- a/complex.c +++ b/complex.c @@ -75,6 +75,20 @@ f_add(VALUE x, VALUE y) return x; if (FIXNUM_ZERO_P(x)) return y; + + if (RB_INTEGER_TYPE_P(x) && + UNLIKELY(rb_method_basic_definition_p(rb_cInteger, idPLUS))) { + return rb_int_plus(x, y); + } + else if (RB_FLOAT_TYPE_P(x) && + UNLIKELY(rb_method_basic_definition_p(rb_cFloat, idPLUS))) { + return rb_float_plus(x, y); + } + else if (RB_TYPE_P(x, T_RATIONAL) && + UNLIKELY(rb_method_basic_definition_p(rb_cRational, idPLUS))) { + return rb_rational_plus(x, y); + } + return rb_funcall(x, '+', 1, y); } diff --git a/internal.h b/internal.h index 9d90c191f2..cb4c06a41e 100644 --- a/internal.h +++ b/internal.h @@ -1655,6 +1655,7 @@ VALUE rb_int_pred(VALUE num); VALUE rb_int_uminus(VALUE num); VALUE rb_float_uminus(VALUE num); VALUE rb_int_plus(VALUE x, VALUE y); +VALUE rb_float_plus(VALUE x, VALUE y); VALUE rb_int_minus(VALUE x, VALUE y); VALUE rb_int_mul(VALUE x, VALUE y); VALUE rb_int_idiv(VALUE x, VALUE y); diff --git a/numeric.c b/numeric.c index ef7c58e870..5e329a1f3d 100644 --- a/numeric.c +++ b/numeric.c @@ -1018,8 +1018,8 @@ rb_float_uminus(VALUE flt) * Returns a new Float which is the sum of +float+ and +other+. */ -static VALUE -flo_plus(VALUE x, VALUE y) +VALUE +rb_float_plus(VALUE x, VALUE y) { if (RB_TYPE_P(y, T_FIXNUM)) { return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y)); @@ -5674,7 +5674,7 @@ Init_Numeric(void) rb_define_alias(rb_cFloat, "inspect", "to_s"); rb_define_method(rb_cFloat, "coerce", flo_coerce, 1); rb_define_method(rb_cFloat, "-@", rb_float_uminus, 0); - rb_define_method(rb_cFloat, "+", flo_plus, 1); + rb_define_method(rb_cFloat, "+", rb_float_plus, 1); rb_define_method(rb_cFloat, "-", flo_minus, 1); rb_define_method(rb_cFloat, "*", flo_mul, 1); rb_define_method(rb_cFloat, "/", flo_div, 1); diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb index 1180e9acb0..daf972f7b4 100644 --- a/test/ruby/test_complex.rb +++ b/test/ruby/test_complex.rb @@ -269,6 +269,36 @@ class Complex_Test < Test::Unit::TestCase assert_equal(Complex(Rational(5,3),Rational(2)), c + Rational(2,3)) end + def test_add_with_redefining_int_plus + assert_in_out_err([], <<-'end;', ['true'], []) + class Integer + def +(other); 42; end + end + a = Complex(1, 2) + Complex(0, 1) + puts a == Complex(1, 42) + end; + end + + def test_add_with_redefining_float_plus + assert_in_out_err([], <<-'end;', ['true'], []) + class Float + def +(other); 42.0; end + end + a = Complex(1, 2.0) + Complex(0, 1) + puts a == Complex(1, 42.0) + end; + end + + def test_add_with_redefining_rational_plus + assert_in_out_err([], <<-'end;', ['true'], []) + class Rational + def +(other); 355/113r; end + end + a = Complex(1, 2r) + Complex(0, 1) + puts a == Complex(1, 355/113r) + end; + end + def test_sub c = Complex(1,2) c2 = Complex(2,3)