Bug #16632

Remove verbose warning on treating keyword splat as positional argument in Ruby 2.6

Added by jeremyevans0 (Jeremy Evans) 10 months ago. Updated 9 months ago.

Target version:
ruby -v:
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-openbsd]


Ruby 2.6 will issue a verbose mode warning if treating a keyword splat as a positional argument if the method does not accept rest arguments or keyword arguments. This is different from Ruby 2.5, 2.7, and the master branch.

$ ruby25 -ve 'def a(b); b end; hash = {bar: 1}; p a(**hash)'
ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-openbsd]

$ ruby26 -ve 'def a(b); b end; hash = {bar: 1}; p a(**hash)'
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-openbsd]
-e:1: warning: in `a': the last argument was passed as a single Hash
-e:1: warning: although a splat keyword arguments here

$ ruby27 -ve 'def a(b); b end; hash = {bar: 1}; p a(**hash)'
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-openbsd]

My guess for the reason for the Ruby 2.6 behavior is it was done before we agreed on the semantics of keyword argument separation. If we were going to drop keyword argument to positional argument conversion for methods that did not accept keyword arguments, it is a reasonable warning. However, since we convert keyword arguments to positional arguments for methods that do not accept keywords, the 2.6 verbose mode warning doesn't make sense and I think should be removed. See attached diff for the removal of the warning and updating of related test.


Related issues

Has duplicate Ruby master - Bug #16950: Stop nonsense keyword argument warnings in 2.6Openusa (Usaku NAKAMURA)Actions

Updated by Dan0042 (Daniel DeLorme) 9 months ago

This is really interesting. It means that mixing double-splat with positional-only methods was already discouraged.

It feels kinda weird to be more strict about keyword/positional separation in general, but to become more more lenient for this case. Another possibility would be to re-add the warning in 2.7 and trunk. The semantics of keyword-to-positional conversion were basically reverse engineered from the 2.6 behavior, so we could say the correct behavior is "however it worked in 2.6" and this part was simply overlooked.

Also I find this gives an interesting alternative view on keyword arguments: the braceless hash syntax can be used either for a positional hash or keywords, but a double splat is specifically for keywords and shouldn't be used with a positional-only method.

I don't really have a strong opinion either way.

Updated by Eregon (Benoit Daloze) 9 months ago

As mentioned in
it seems very unlikely this triggers in practice, because indeed who would bother with an extra ** when the method doesn't take keyword arguments?
Maybe for the case the user thinks the method takes keyword arguments but it doesn't (yet, maybe the next gem version does)?

Anyway, agreed with Jeremy, no point to warn about something which no longer warns in more recent versions.
Warning ** but not foo: 1 as a special case seems to just make things more complicated.

Updated by jeremyevans0 (Jeremy Evans) 9 months ago

Looking through the repository history, the patch attached to this issue is mostly implemented by 6424d316b993ecceb6f583ae476096274e304788, so that commit could be backported instead, though I'm not sure it applies without conflicts.


Updated by jeremyevans0 (Jeremy Evans) 6 months ago

  • Has duplicate Bug #16950: Stop nonsense keyword argument warnings in 2.6 added

Also available in: Atom PDF