[前][次][番号順一覧][スレッド一覧]

ruby-changes:45067

From: nobu <ko1@a...>
Date: Wed, 21 Dec 2016 21:06:43 +0900 (JST)
Subject: [ruby-changes:45067] nobu:r57140 (trunk): time.c: refine num_exact error message

nobu	2016-12-21 21:06:40 +0900 (Wed, 21 Dec 2016)

  New Revision: 57140

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57140

  Log:
    time.c: refine num_exact error message
    
    * time.c (num_exact): show the original argument when conversion
      failed, instead of intermediate nil.

  Modified files:
    trunk/test/ruby/test_time.rb
    trunk/time.c
Index: time.c
===================================================================
--- time.c	(revision 57139)
+++ time.c	(revision 57140)
@@ -482,51 +482,44 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/time.c#L482
 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));
     }
Index: test/ruby/test_time.rb
===================================================================
--- test/ruby/test_time.rb	(revision 57139)
+++ test/ruby/test_time.rb	(revision 57140)
@@ -1089,4 +1089,14 @@ class TestTime < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_time.rb#L1089
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]