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/