From: nobu@... Date: 2017-02-06T04:09:35+00:00 Subject: [ruby-core:79451] [Ruby trunk Bug#13196] Improve keyword argument errors when non-keyword arguments given Issue #13196 has been updated by Nobuyoshi Nakada. How about this? ``` $ ./miniruby -e 'def explode(code:)end' -e 'explode(1)' -e:1:in `explode': wrong number of arguments (given 1, expected 0 with required keyword code) (ArgumentError) from -e:2:in `
' ``` ```diff diff --git a/vm_args.c b/vm_args.c index 6cded80924..76516f60e0 100644 --- a/vm_args.c +++ b/vm_args.c @@ -725,7 +725,25 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc) 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) { + VALUE mesg = rb_attr_get(exc, idMesg); + rb_str_resize(mesg, RSTRING_LEN(mesg)-1); + rb_str_cat_cstr(mesg, " with required keyword"); + if (req_key_num > 1) rb_str_cat_cstr(mesg, "s"); + 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 ``` ---------------------------------------- Bug #13196: Improve keyword argument errors when non-keyword arguments given https://bugs.ruby-lang.org/issues/13196#change-62883 * Author: Olivier Lacan * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- Given the following method definition: ```ruby def explode(code:) puts "Boom!" end ``` If a Ruby user doesn't provide any arguments when calling the `explode` method, the following helpful feedback is given: ```ruby explode ArgumentError: missing keyword: code ``` But when a Ruby user mistakenly provides a regular argument, the exception message is obtuse and unhelpful: ```ruby explode "1234" ArgumentError: wrong number of arguments (given 1, expected 0) ``` This does not provide information to properly recover from the error. Worse, it's incorrect. It is not true that the method expected 0 arguments. The method expected 1 keyword argument. Instead, Ruby should respond something like: ```ruby explode "1234" ArgumentError: missing keyword: code, given "1234" which is not a keyword argument. ``` One could argue that this situation would call for a different error class, perhaps a `KeywordArgumentError` that would inherit from `ArgumentError`, but that would extend the scope of this feature request a bit too far in my mind. -- https://bugs.ruby-lang.org/ Unsubscribe: