
Issue #20251 has been updated by jeremyevans0 (Jeremy Evans). phillipp (Phillipp Röll) wrote in #note-3:
I know and unserstand that, but still, is the raised exception not wrong? Should that not be `ArgumentError: unknown keyword: :name`?
Positional argument arity is checked before keyword arguments are checked. I don't think it makes sense to delay raising the error to try to find all additional possible errors. Certainly just showing `unknown keyword: :name` is wrong, because even if you removed the keyword argument, the call would still have a positional argument arity error. I think your main conceptual problem is here:
the Hash (passed without the brackets, but that is not needed in other cases) would be accepted as the params argument or
This is inaccurate starting in Ruby 3. Keyword arguments are separated from positional arguments. For backwards compatibility, a method that does not accept keyword arguments will convert the keyword arguments to a hash. However, the call itself does not pass a hash, it passes keywords. See https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-ke... for details. ---------------------------------------- Bug #20251: Wrong ArgumentError raised for hash as last parameter before keyword aguments https://bugs.ruby-lang.org/issues/20251#change-106671 * Author: phillipp (Phillipp Röll) * Status: Feedback * Priority: Normal * ruby -v: ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Suppose we have the following method as part of an API client: ``` def post(path, params, timeout: 30) end ``` The method is then called like this: ``` post("/persons", name: "John Doe") ``` This leads to an error message `ArgumentError: wrong number of arguments (given 1, expected 2)`. I suppose the (implicit) hash is used for keyword arguments. My expectation would be, that: 1. the Hash (passed without the brackets, but that is not needed in other cases) would be accepted as the `params` argument _or_ 2. that an `ArgumentError` would be raised with the message `ArgumentError: unknown keyword: :name` In my opinion, the first case should be what's happening, the second behaviour would be my expectation if that's not possible, because a hash without brackets can't be mixed without passing keyword arguments. Either way, starting with Ruby 3.0, the behaviour makes no sense to me anymore. -- https://bugs.ruby-lang.org/