From 5518b5c21a2168e45aa2382344583178cbb83c13 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 21 Dec 2016 12:06:40 +0000 Subject: [PATCH] time.c: refine num_exact error message * time.c (num_exact): show the original argument when conversion failed, instead of intermediate nil. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57140 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/ruby/test_time.rb | 10 ++++++++ time.c | 55 ++++++++++++++++++------------------------ 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb index 60bed87c9c..d3a8645024 100644 --- a/test/ruby/test_time.rb +++ b/test/ruby/test_time.rb @@ -1089,4 +1089,14 @@ class TestTime < Test::Unit::TestCase t = Time.utc(2017, 1, 1, 1, 0, 0).getlocal("-05:00") assert_equal("366", t.strftime("%j")) end + + def test_num_exact_error + bad = EnvUtil.labeled_class("BadValue").new + x = EnvUtil.labeled_class("Inexact") do + def to_s; "Inexact"; end + define_method(:to_int) {bad} + define_method(:to_r) {bad} + end.new + assert_raise_with_message(TypeError, /Inexact/) {Time.at(x)} + end end diff --git a/time.c b/time.c index e3c1426b57..a99444fce1 100644 --- a/time.c +++ b/time.c @@ -482,51 +482,44 @@ static VALUE num_exact(VALUE v) { VALUE tmp; - int t; - t = TYPE(v); - switch (t) { - case T_FIXNUM: - case T_BIGNUM: + if (NIL_P(v)) { + rb_raise(rb_eTypeError, "can't convert nil into an exact number"); + } + else if (RB_INTEGER_TYPE_P(v)) { return v; - - case T_RATIONAL: - break; - - case T_STRING: - case T_NIL: + } + else if (RB_TYPE_P(v, T_RATIONAL)) { + goto rational; + } + else if (RB_TYPE_P(v, T_STRING)) { goto typeerror; - - default: + } + else { if ((tmp = rb_check_funcall(v, rb_intern("to_r"), 0, NULL)) != Qundef) { /* test to_int method availability to reject non-Numeric * objects such as String, Time, etc which have to_r method. */ if (!rb_respond_to(v, rb_intern("to_int"))) goto typeerror; - v = tmp; - break; } - if (!NIL_P(tmp = rb_check_to_integer(v, "to_int"))) { - v = tmp; - break; + else if (!NIL_P(tmp = rb_check_to_int(v))) { + return tmp; + } + else { + goto typeerror; } - goto typeerror; } - t = TYPE(v); - switch (t) { - case T_FIXNUM: - case T_BIGNUM: - return v; - - case T_RATIONAL: + if (RB_INTEGER_TYPE_P(tmp)) { + v = tmp; + } + else if (RB_TYPE_P(tmp, T_RATIONAL)) { + v = tmp; + rational: if (RRATIONAL(v)->den == INT2FIX(1)) v = RRATIONAL(v)->num; - break; - - default: + } + else { typeerror: - if (NIL_P(v)) - rb_raise(rb_eTypeError, "can't convert nil into an exact number"); rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into an exact number", rb_obj_class(v)); }