From bcf08dca958c1d15f3eb486cb8f52304c7674001 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Thu, 25 Jul 2019 08:24:59 -0700 Subject: [PATCH] Make Kernel.Rational handle options that respond to to_int but not to_r Fixes [Bug #12485] --- rational.c | 6 ++++++ test/ruby/test_rational.rb | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/rational.c b/rational.c index 7113e15e8e..59f2c89bcb 100644 --- a/rational.c +++ b/rational.c @@ -2575,6 +2575,9 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) a1 = string_to_r_strict(a1, raise); if (!raise && NIL_P(a1)) return Qnil; } + else if (!rb_respond_to(a1, idTo_r) && rb_respond_to(a1, rb_intern("to_int"))) { + a1 = rb_to_int(a1); + } if (RB_FLOAT_TYPE_P(a2)) { a2 = float_to_r(a2); @@ -2583,6 +2586,9 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) a2 = string_to_r_strict(a2, raise); if (!raise && NIL_P(a2)) return Qnil; } + else if (a2 != Qundef && !rb_respond_to(a2, idTo_r) && rb_respond_to(a2, rb_intern("to_int"))) { + a2 = rb_to_int(a2); + } if (RB_TYPE_P(a1, T_RATIONAL)) { if (a2 == Qundef || (k_exact_one_p(a2))) diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index 301890b620..437cfa1796 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -158,6 +158,12 @@ def o.to_r; raise; end if (1.0/0).infinite? assert_raise(FloatDomainError){Rational(1.0/0)} end + + o = Object.new + def o.to_int; 1; end + assert_equal(1, Rational(o, 1)) + assert_equal(1, Rational(1, o)) + assert_equal(1, Rational(o, o)) end def test_attr -- 2.21.0