summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rational.c10
-rw-r--r--test/ruby/test_rational.rb8
2 files changed, 17 insertions, 1 deletions
diff --git a/rational.c b/rational.c
index 31768702a5..abf33313bb 100644
--- a/rational.c
+++ b/rational.c
@@ -2673,8 +2673,16 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise)
}
}
if ((k_numeric_p(a1) && k_numeric_p(a2)) &&
- (!f_integer_p(a1) || !f_integer_p(a2)))
+ (!f_integer_p(a1) || !f_integer_p(a2))) {
+ VALUE tmp = rb_protect(to_rational, a1, &state);
+ if (!state) {
+ a1 = tmp;
+ }
+ else {
+ rb_set_errinfo(Qnil);
+ }
return f_div(a1, a2);
+ }
}
a1 = nurat_int_value(a1);
diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb
index 5bdf5b717e..e89b74d39e 100644
--- a/test/ruby/test_rational.rb
+++ b/test/ruby/test_rational.rb
@@ -165,6 +165,14 @@ class Rational_Test < Test::Unit::TestCase
if (1.0/0).infinite?
assert_raise(FloatDomainError){Rational(1.0/0)}
end
+
+ bug16518 = "[ruby-core:96942] [Bug #16518]"
+ cls = Class.new(Numeric) do
+ def /(y); 42; end
+ def to_r; 1r; end
+ def to_int; 1; end
+ end
+ assert_equal(1/2r, Rational(cls.new, 2))
end
def test_attr