summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--complex.c14
-rw-r--r--internal.h1
-rw-r--r--numeric.c6
-rw-r--r--test/ruby/test_complex.rb30
4 files changed, 48 insertions, 3 deletions
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)