
Issue #20440 has been updated by zverok (Victor Shepelev).
What still seems off to me is that super is modifying the arguments.
If I understand correctly, what “modifies” the argument is child’s `foo` signature: ```ruby def foo(*) # <= this says “accept only positional args” (implicitly converting keyword ones to hash) super # <= this implicitly has a signature same as foo: super(*), passing only positional ones to the parent end ``` The way to “fix” the code (if you own it) is this: ```ruby class Child < Base def foo(*, **) # the declaration that leaves keyword ones and positional ones separated puts "Child: calling foo" super # super is implicitly called as super(*, **), passing them separately end end ``` The printed output: ``` Base: calling foo! with x: 1 Child: calling foo Base: calling foo with args: [], x: 1 ``` ---------------------------------------- Bug #20440: `super` from child class duplicating a keyword argument as a positional Hash https://bugs.ruby-lang.org/issues/20440#change-108038 * Author: ozydingo (Andrew Schwartz) * Status: Closed * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- Apologies for the verbose title, but that's the specific set of conditions that AFAICT are required to reproduce the bug! Here's the simplest setup I can reproduce: ```rb class Base def foo(*args, x: 1) puts "Base: calling foo with args: #{args}, x: #{x}" end def foo!(x: 1) puts "Base: calling foo! with x: #{x}" foo(x: x) end end class Child < Base def foo(*) puts "Child: calling foo" super end end ``` When I call `Child.new.foo!`, I expect it to call the base class method `foo!`, which will use the default keyword arg `x: 1`; then the child method `foo` with `x: 1`, and finally the base method `foo` with `x: 1`. However, this is not what I observe: ```rb Child.new.foo! Base: calling foo! with x: 1 Child: calling foo Base: calling foo with args: [{:x=>1}], x: 1 ``` So when the child `foo` method called `super`, it passed not only `x: 1` as a keyword arg, but *also* `{x: 1}` as a Hash positional arg to the super method. This is breaking my upgrade to Ruby 3.0 as I have a similar setup but without the `*args` param, this I am getting the error "wrong number of arguments (given 1, expected 0)". -- https://bugs.ruby-lang.org/