diff options
author | Kenta Murata <mrkn@users.noreply.github.com> | 2020-10-22 17:59:52 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-22 17:59:52 +0900 |
commit | d23d5c3130a0944e7e591370cbf8599009318a7c (patch) | |
tree | 1133a91f7a511d669ba300a7619927806ece8849 /rational.c | |
parent | 603fb940c0d334f399d77b56d7e62ee85edb91e0 (diff) |
rational.c: try converting by to_int in Rational() (#3684)
[Bug #12485]
Notes
Notes:
Merged-By: mrkn <mrkn@ruby-lang.org>
Diffstat (limited to 'rational.c')
-rw-r--r-- | rational.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/rational.c b/rational.c index 6ac42bff04..31768702a5 100644 --- a/rational.c +++ b/rational.c @@ -2573,6 +2573,8 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) VALUE a1 = numv, a2 = denv; int state; + assert(a1 != Qundef); + if (NIL_P(a1) || NIL_P(a2)) { if (!raise) return Qnil; 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; } - 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); } + else if (RB_TYPE_P(a1, T_RATIONAL)) { + // nothing to do + } else if (RB_TYPE_P(a1, T_STRING)) { a1 = string_to_r_strict(a1, raise); 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); } + else if (RB_TYPE_P(a2, T_RATIONAL)) { + // nothing to do + } else if (RB_TYPE_P(a2, T_STRING)) { a2 = string_to_r_strict(a2, raise); 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 (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 (!k_integer_p(a1)) { + if (!RB_INTEGER_TYPE_P(a1)) { if (!raise) { VALUE result = rb_protect(to_rational, a1, NULL); rb_set_errinfo(Qnil); |