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/