Bug #8993


Request for clarification on method argument binding for keyword arguments

Added by 97jaz (Jon Zeppieri) over 8 years ago. Updated over 8 years ago.

Target version:
ruby -v:


I recently fixed keyword arguments in the JRuby interpreter, and I then found an example for which MRI and JRuby have different behavior:

def foo(a, b, c=1, *d, e, f:2, **g)
[a, b, c, d, e, f, g]

foo(1, 2, f:5)

MRI raises:
ArgumentError: wrong number of arguments (2 for 3+)

... whereas JRuby produces:

[1, 2, 1, [], {:f=>5}, 2, {}]

I implemented the behavior in JRuby to conform with MRI, but in this case, I think that JRuby's behavior is correct, based upon the discussion in #8040.

Is there a spec for this feature somewhere (aside from the RSpec specs that I submitted to the RubySpec project)? In #7529, Matz refers to "the spec" for this feature, but I don't know where or what that is.

Updated by nobu (Nobuyoshi Nakada) over 8 years ago

  • Description updated (diff)

JRuby's behavior is equal to MRI older than fixing #8040.

If the last argument is a Hash, and the method defines keyword arguments, the last argument is used as the keyword arguments.

Updated by 97jaz (Jon Zeppieri) over 8 years ago

I don't believe that's true. If I understand #8040 correctly, it's change is well summarized in comment 2:

But, it may be good that we consider the hash for a keyword only when the number of arguments is more than the expected mandatory parameters.

In the example above, foo takes three mandatory parameters: a, b, and e. The call to foo passes exactly three parameters. Therefore, according to the logic described in #8040, none of them should be treated as keyword arguments.

JRuby's interpreter does not treat f:5 as a keyword argument; it binds {f: 5} to e.

MRI, on the other hand, does treat it as a keyword argument, so it raises an exception, complaining that not all required parameters have been provided.

Updated by 97jaz (Jon Zeppieri) over 8 years ago

No update on this? In case my previous posts were too confusing, here's the gist of it:

As far as I can tell, MRI does not implement the behavior that #8040 describes, so I think this is a bug.

Updated by zzak (Zachary Scott) over 8 years ago

  • Status changed from Open to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)

@nobu (Nobuyoshi Nakada) can you confirm this as a bug?

Perhaps it's simply a doc bug like #8905 and #8952

Please reassign to me if it's a doc bug.

Updated by marcandre (Marc-Andre Lafortune) over 8 years ago

This is a bug and JRuby's behavior is correct.

Actions #6

Updated by nobu (Nobuyoshi Nakada) over 8 years ago

  • Tracker changed from Misc to Bug
Actions #7

Updated by nobu (Nobuyoshi Nakada) over 8 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r44207.
Jon, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

vm_insnhelper.c: post arguments as mandatory

  • vm_insnhelper.c (vm_callee_setup_arg_complex): count post
    arguments as mandatory arguments. [ruby-core:57706] [Bug #8993]
  • vm_insnhelper.c (vm_yield_setup_block_args): ditto.

Also available in: Atom PDF