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

ruby-changes:47144

From: nobu <ko1@a...>
Date: Tue, 4 Jul 2017 14:42:09 +0900 (JST)
Subject: [ruby-changes:47144] nobu:r59259 (trunk): vm_args.c: improve keyword argument errors

nobu	2017-07-04 14:42:04 +0900 (Tue, 04 Jul 2017)

  New Revision: 59259

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

  Log:
    vm_args.c: improve keyword argument errors
    
    * vm_args.c (argument_arity_error): improve required keyword
      argument errors when non-keyword arguments given.
      [ruby-core:79439] [Bug #13196]

  Modified files:
    trunk/test/ruby/test_keyword.rb
    trunk/vm_args.c
Index: test/ruby/test_keyword.rb
===================================================================
--- test/ruby/test_keyword.rb	(revision 59258)
+++ test/ruby/test_keyword.rb	(revision 59259)
@@ -641,4 +641,17 @@ class TestKeywordArguments < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L641
     assert_equal(x, result)
     assert_kind_of(klass, result, bug12884)
   end
+
+  def test_arity_error_message
+    obj = Object.new
+    def obj.t(x:) end
+    assert_raise_with_message(ArgumentError, /required keyword: x\)/) do
+      obj.t(42)
+    end
+    obj = Object.new
+    def obj.t(x:, y:, z: nil) end
+    assert_raise_with_message(ArgumentError, /required keywords: x, y\)/) do
+      obj.t(42)
+    end
+  end
 end
Index: vm_args.c
===================================================================
--- vm_args.c	(revision 59258)
+++ vm_args.c	(revision 59259)
@@ -719,7 +719,26 @@ raise_argument_error(rb_thread_t *th, co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L719
 static void
 argument_arity_error(rb_thread_t *th, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
 {
-    raise_argument_error(th, iseq, rb_arity_error_new(miss_argc, min_argc, max_argc));
+    VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
+    if (iseq->body->param.flags.has_kw) {
+	const struct rb_iseq_param_keyword *const kw = iseq->body->param.keyword;
+	const ID *keywords = kw->table;
+	int req_key_num = kw->required_num;
+	if (req_key_num > 0) {
+	    static const char required[] = "; required keywords";
+	    VALUE mesg = rb_attr_get(exc, idMesg);
+	    rb_str_resize(mesg, RSTRING_LEN(mesg)-1);
+	    rb_str_cat(mesg, required, sizeof(required) - 1 - (req_key_num == 1));
+	    rb_str_cat_cstr(mesg, ":");
+	    do {
+		rb_str_cat_cstr(mesg, " ");
+		rb_str_append(mesg, rb_id2str(*keywords++));
+		rb_str_cat_cstr(mesg, ",");
+	    } while (--req_key_num);
+	    RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
+	}
+    }
+    raise_argument_error(th, iseq, exc);
 }
 
 static void

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

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