Issue #20441 has been updated by zverok (Victor Shepelev).
Why does this conversion to a Hash occur?
Because of backward compatibility, indeed. Even now, most of, say, Rails code still uses
“old” conventions:
```ruby
def foo(arg1, arg2, options = {})
# ...
end
# and expects it to be called as
foo("bar", 1, opt1: val1, opt2: val3)
```
Prohibiting this (and requiring to pass to such methods only explicit hashes like
`foo("bar", 1, {opt1: val1, opt2: val3})`) would break an enormous amount of
code.
So, the last hash-like pack of arguments would be treated as keyword args for methods with
them in the signature and as a last positional hash for methods without them.
The question of “generic delegation” in such conditions (with `super` or otherwise) is a
subtle one, but it is mostly solved and requires following only two rules, as was
[
explained](https://bugs.ruby-lang.org/issues/20440#note-3) in the previous ticket:
* For Ruby 3+, to “delegate all possible kinds of arguments”, use `foo(*, **)`
* If the code needs to be compatible with Ruby < 3, use `ruby2_keywords`
If we do neither, the method defined as `foo(*)` wouldn’t try to guess how to convert its
arguments back to positional+keyword on `super` or other forms of delegation and would
simply consider them all positional.
----------------------------------------
Misc #20441: Should passing keyword args to method_name(*) be an error?
https://bugs.ruby-lang.org/issues/20441#change-108042
* Author: ozydingo (Andrew Schwartz)
* Status: Open
----------------------------------------
In the following method:
```rb
def foo(*)
super
end
```
it is apparently the intended ruby 3 behavior to pass keyword args as a positional Hash to
`super`. I believe this is confusing and can lead to hidden and hard-to-discover bugs
(e.g. #20440). Since `*` is meant to only represent positional args, should it be an
ArgumentError to pass keyword args at all to this method? Similar to how it is an error to
pass positions args to `bar(**)`.
--
https://bugs.ruby-lang.org/