1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2016-12-21 12:06:40 +00:00
parent 33e8eef020
commit 5518b5c21a
2 changed files with 34 additions and 31 deletions

View file

@ -1089,4 +1089,14 @@ class TestTime < Test::Unit::TestCase
t = Time.utc(2017, 1, 1, 1, 0, 0).getlocal("-05:00") t = Time.utc(2017, 1, 1, 1, 0, 0).getlocal("-05:00")
assert_equal("366", t.strftime("%j")) assert_equal("366", t.strftime("%j"))
end 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 end

53
time.c
View file

@ -482,51 +482,44 @@ static VALUE
num_exact(VALUE v) num_exact(VALUE v)
{ {
VALUE tmp; VALUE tmp;
int t;
t = TYPE(v); if (NIL_P(v)) {
switch (t) { rb_raise(rb_eTypeError, "can't convert nil into an exact number");
case T_FIXNUM: }
case T_BIGNUM: else if (RB_INTEGER_TYPE_P(v)) {
return v; return v;
}
case T_RATIONAL: else if (RB_TYPE_P(v, T_RATIONAL)) {
break; goto rational;
}
case T_STRING: else if (RB_TYPE_P(v, T_STRING)) {
case T_NIL:
goto typeerror; goto typeerror;
}
default: else {
if ((tmp = rb_check_funcall(v, rb_intern("to_r"), 0, NULL)) != Qundef) { if ((tmp = rb_check_funcall(v, rb_intern("to_r"), 0, NULL)) != Qundef) {
/* test to_int method availability to reject non-Numeric /* test to_int method availability to reject non-Numeric
* objects such as String, Time, etc which have to_r method. */ * objects such as String, Time, etc which have to_r method. */
if (!rb_respond_to(v, rb_intern("to_int"))) goto typeerror; 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"))) { else if (!NIL_P(tmp = rb_check_to_int(v))) {
v = tmp; return tmp;
break;
} }
else {
goto typeerror; goto typeerror;
} }
}
t = TYPE(v); if (RB_INTEGER_TYPE_P(tmp)) {
switch (t) { v = tmp;
case T_FIXNUM: }
case T_BIGNUM: else if (RB_TYPE_P(tmp, T_RATIONAL)) {
return v; v = tmp;
rational:
case T_RATIONAL:
if (RRATIONAL(v)->den == INT2FIX(1)) if (RRATIONAL(v)->den == INT2FIX(1))
v = RRATIONAL(v)->num; v = RRATIONAL(v)->num;
break; }
else {
default:
typeerror: 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_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into an exact number",
rb_obj_class(v)); rb_obj_class(v));
} }