mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
rational.c: try converting by to_int in Rational() (#3684)
[Bug #12485]
This commit is contained in:
parent
603fb940c0
commit
d23d5c3130
Notes:
git
2020-10-22 18:00:33 +09:00
Merged-By: mrkn <mrkn@ruby-lang.org>
2 changed files with 50 additions and 3 deletions
34
rational.c
34
rational.c
|
@ -2573,6 +2573,8 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise)
|
||||||
VALUE a1 = numv, a2 = denv;
|
VALUE a1 = numv, a2 = denv;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
|
assert(a1 != Qundef);
|
||||||
|
|
||||||
if (NIL_P(a1) || NIL_P(a2)) {
|
if (NIL_P(a1) || NIL_P(a2)) {
|
||||||
if (!raise) return Qnil;
|
if (!raise) return Qnil;
|
||||||
rb_raise(rb_eTypeError, "can't convert nil into Rational");
|
rb_raise(rb_eTypeError, "can't convert nil into Rational");
|
||||||
|
@ -2588,21 +2590,47 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise)
|
||||||
a2 = RCOMPLEX(a2)->real;
|
a2 = RCOMPLEX(a2)->real;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RB_FLOAT_TYPE_P(a1)) {
|
if (RB_INTEGER_TYPE_P(a1)) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a1)) {
|
||||||
a1 = float_to_r(a1);
|
a1 = float_to_r(a1);
|
||||||
}
|
}
|
||||||
|
else if (RB_TYPE_P(a1, T_RATIONAL)) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
else if (RB_TYPE_P(a1, T_STRING)) {
|
else if (RB_TYPE_P(a1, T_STRING)) {
|
||||||
a1 = string_to_r_strict(a1, raise);
|
a1 = string_to_r_strict(a1, raise);
|
||||||
if (!raise && NIL_P(a1)) return Qnil;
|
if (!raise && NIL_P(a1)) return Qnil;
|
||||||
}
|
}
|
||||||
|
else if (!rb_respond_to(a1, idTo_r)) {
|
||||||
|
VALUE tmp = rb_protect(rb_check_to_int, a1, NULL);
|
||||||
|
rb_set_errinfo(Qnil);
|
||||||
|
if (!NIL_P(tmp)) {
|
||||||
|
a1 = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (RB_FLOAT_TYPE_P(a2)) {
|
if (RB_INTEGER_TYPE_P(a2)) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
else if (RB_FLOAT_TYPE_P(a2)) {
|
||||||
a2 = float_to_r(a2);
|
a2 = float_to_r(a2);
|
||||||
}
|
}
|
||||||
|
else if (RB_TYPE_P(a2, T_RATIONAL)) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
else if (RB_TYPE_P(a2, T_STRING)) {
|
else if (RB_TYPE_P(a2, T_STRING)) {
|
||||||
a2 = string_to_r_strict(a2, raise);
|
a2 = string_to_r_strict(a2, raise);
|
||||||
if (!raise && NIL_P(a2)) return Qnil;
|
if (!raise && NIL_P(a2)) return Qnil;
|
||||||
}
|
}
|
||||||
|
else if (a2 != Qundef && !rb_respond_to(a2, idTo_r)) {
|
||||||
|
VALUE tmp = rb_protect(rb_check_to_int, a2, NULL);
|
||||||
|
rb_set_errinfo(Qnil);
|
||||||
|
if (!NIL_P(tmp)) {
|
||||||
|
a2 = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (RB_TYPE_P(a1, T_RATIONAL)) {
|
if (RB_TYPE_P(a1, T_RATIONAL)) {
|
||||||
if (a2 == Qundef || (k_exact_one_p(a2)))
|
if (a2 == Qundef || (k_exact_one_p(a2)))
|
||||||
|
@ -2610,7 +2638,7 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a2 == Qundef) {
|
if (a2 == Qundef) {
|
||||||
if (!k_integer_p(a1)) {
|
if (!RB_INTEGER_TYPE_P(a1)) {
|
||||||
if (!raise) {
|
if (!raise) {
|
||||||
VALUE result = rb_protect(to_rational, a1, NULL);
|
VALUE result = rb_protect(to_rational, a1, NULL);
|
||||||
rb_set_errinfo(Qnil);
|
rb_set_errinfo(Qnil);
|
||||||
|
|
|
@ -128,6 +128,13 @@ class Rational_Test < Test::Unit::TestCase
|
||||||
assert_raise(TypeError){Rational(Object.new, Object.new)}
|
assert_raise(TypeError){Rational(Object.new, Object.new)}
|
||||||
assert_raise(TypeError){Rational(1, Object.new)}
|
assert_raise(TypeError){Rational(1, Object.new)}
|
||||||
|
|
||||||
|
bug12485 = '[ruby-core:75995] [Bug #12485]'
|
||||||
|
o = Object.new
|
||||||
|
def o.to_int; 1; end
|
||||||
|
assert_equal(1, Rational(o, 1), bug12485)
|
||||||
|
assert_equal(1, Rational(1, o), bug12485)
|
||||||
|
assert_equal(1, Rational(o, o), bug12485)
|
||||||
|
|
||||||
o = Object.new
|
o = Object.new
|
||||||
def o.to_r; 1/42r; end
|
def o.to_r; 1/42r; end
|
||||||
assert_equal(1/42r, Rational(o))
|
assert_equal(1/42r, Rational(o))
|
||||||
|
@ -834,6 +841,18 @@ class Rational_Test < Test::Unit::TestCase
|
||||||
assert_equal(nil, Rational(1, Object.new, exception: false))
|
assert_equal(nil, Rational(1, Object.new, exception: false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bug12485 = '[ruby-core:75995] [Bug #12485]'
|
||||||
|
assert_nothing_raised(RuntimeError, bug12485) {
|
||||||
|
o = Object.new
|
||||||
|
def o.to_int; raise; end
|
||||||
|
assert_equal(nil, Rational(o, exception: false))
|
||||||
|
}
|
||||||
|
assert_nothing_raised(RuntimeError, bug12485) {
|
||||||
|
o = Object.new
|
||||||
|
def o.to_int; raise; end
|
||||||
|
assert_equal(nil, Rational(1, o, exception: false))
|
||||||
|
}
|
||||||
|
|
||||||
o = Object.new;
|
o = Object.new;
|
||||||
def o.to_r; raise; end
|
def o.to_r; raise; end
|
||||||
assert_nothing_raised(RuntimeError) {
|
assert_nothing_raised(RuntimeError) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue