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

ruby-changes:47801

From: nobu <ko1@a...>
Date: Fri, 15 Sep 2017 11:02:04 +0900 (JST)
Subject: [ruby-changes:47801] nobu:r59919 (trunk): object.c: fix conversion failure message

nobu	2017-09-15 11:01:59 +0900 (Fri, 15 Sep 2017)

  New Revision: 59919

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

  Log:
    object.c: fix conversion failure message
    
    * object.c (convert_type_with_id): fix failure message for
      explicit conversion.  rb_convert_type_with_id and
      rb_check_convert_type_with_id are not only for implicit
      conversions.

  Modified files:
    trunk/object.c
    trunk/test/ruby/test_object.rb
Index: test/ruby/test_object.rb
===================================================================
--- test/ruby/test_object.rb	(revision 59918)
+++ test/ruby/test_object.rb	(revision 59919)
@@ -923,6 +923,7 @@ class TestObject < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_object.rb#L923
     _issue = "Bug #7539"
     assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
     assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
+    assert_raise_with_message(TypeError, "can't convert Array into Rational") {Rational([42])}
   end
 
   def test_copied_ivar_memory_leak
Index: object.c
===================================================================
--- object.c	(revision 59918)
+++ object.c	(revision 59919)
@@ -2885,13 +2885,33 @@ static const struct conv_method_tbl { https://github.com/ruby/ruby/blob/trunk/object.c#L2885
 };
 #define IMPLICIT_CONVERSIONS 7
 
+static int
+conv_method_index(const char *method)
+{
+    static const char prefix[] = "to_";
+
+    if (strncmp(prefix, method, sizeof(prefix)-1) == 0) {
+	const char *const meth = &method[sizeof(prefix)-1];
+	int i;
+	for (i=0; i < numberof(conv_method_names); i++) {
+	    if (conv_method_names[i].method[0] == meth[0] &&
+		strcmp(conv_method_names[i].method, meth) == 0) {
+		return i;
+	    }
+	}
+    }
+    return numberof(conv_method_names);
+}
+
 static VALUE
 convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int index)
 {
     VALUE r = rb_check_funcall(val, method, 0, 0);
     if (r == Qundef) {
 	if (raise) {
-	    const char *msg = index < IMPLICIT_CONVERSIONS ?
+	    const char *msg =
+		((index < 0 ? conv_method_index(rb_id2name(method)) : index)
+		 < IMPLICIT_CONVERSIONS) ?
 		"no implicit conversion of" : "can't convert";
 	    const char *cname = NIL_P(val) ? "nil" :
 		val == Qtrue ? "true" :
@@ -2911,21 +2931,9 @@ convert_type_with_id(VALUE val, const ch https://github.com/ruby/ruby/blob/trunk/object.c#L2931
 static VALUE
 convert_type(VALUE val, const char *tname, const char *method, int raise)
 {
-    ID m = 0;
-    int i = numberof(conv_method_names);
-    static const char prefix[] = "to_";
-
-    if (strncmp(prefix, method, sizeof(prefix)-1) == 0) {
-	const char *const meth = &method[sizeof(prefix)-1];
-	for (i=0; i < numberof(conv_method_names); i++) {
-	    if (conv_method_names[i].method[0] == meth[0] &&
-		strcmp(conv_method_names[i].method, meth) == 0) {
-		m = conv_method_names[i].id;
-		break;
-	    }
-	}
-    }
-    if (!m) m = rb_intern(method);
+    int i = conv_method_index(method);
+    ID m = i < numberof(conv_method_names) ?
+	conv_method_names[i].id : rb_intern(method);
     return convert_type_with_id(val, tname, m, raise, i);
 }
 
@@ -2973,7 +2981,7 @@ rb_convert_type_with_id(VALUE val, int t https://github.com/ruby/ruby/blob/trunk/object.c#L2981
     VALUE v;
 
     if (TYPE(val) == type) return val;
-    v = convert_type_with_id(val, tname, method, TRUE, 0);
+    v = convert_type_with_id(val, tname, method, TRUE, -1);
     if (TYPE(v) != type) {
 	conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
     }
@@ -3017,7 +3025,7 @@ rb_check_convert_type_with_id(VALUE val, https://github.com/ruby/ruby/blob/trunk/object.c#L3025
 
     /* always convert T_DATA */
     if (TYPE(val) == type && type != T_DATA) return val;
-    v = convert_type_with_id(val, tname, method, FALSE, 0);
+    v = convert_type_with_id(val, tname, method, FALSE, -1);
     if (NIL_P(v)) return Qnil;
     if (TYPE(v) != type) {
 	conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);

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

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