
Issue #20392 has been updated by tenderlovemaking (Aaron Patterson). Dan0042 (Daniel DeLorme) wrote in #note-1:
In Ruby 3.2, example 3 raised an exception "both block arg and actual block given" So this looks like a Ruby 3.3 regression.
Thanks, I should have checked older versions. According to git bisect, this was introduced in fdc329ea6f5bce922e95645a0c2118cfd3e1cdea (though I'm not sure how that commit caused this) jeremyevans0 (Jeremy Evans) wrote in #note-2:
`super(...){}`should be a syntax error, just as `foo(...){}` is.
`super` behavior in general is special. For example, `super(arg)` is not a zsuper, but still passes the block implicitly, you have to do `super(arg, &nil)` to avoid passing a block. `super{}` passes the args implicitly, but uses the block given. While I find that confusing, I don't think changing that behavior is worth it, as the backwards compatibility breakage is not worth the benefit IMO.
It's very odd behavior, but I definitely agree. ---------------------------------------- Bug #20392: Delegate super calls with a block https://bugs.ruby-lang.org/issues/20392#change-107456 * Author: tenderlovemaking (Aaron Patterson) * Status: Open * ruby -v: ruby 3.4.0dev (2024-03-15T18:08:39Z master e3a82d79fd) [arm64-darwin23] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- I'm seeing strange behavior with calls to `super` when combined with `...` and a block. I'm not sure if this is expected behavior or not, so I'm filing this ticket. Using delegate `...` with an explicit block will cause an error: ```ruby # Example 1 def foo ... yield end def bar ... foo(...) { } # test.rb: test.rb:6: both block arg and actual block given (SyntaxError) end ``` However, calling `super` and passing a block works: ``` # Example 2 class A def foo yield(3) end end class B < A def foo(...) super do |x| yield(2 + x) end end end p B.new.foo { |x| x } # 5 ``` In the above code, I imagine the bare `super` to basically be equivalent of `super(...)` since I defined the method `foo` as `foo(...)`. However, if I explicitly pass `...` to super, there is no syntax error, just the block I provided is ignored: ```ruby # Example 3 class A def foo yield(3) end end class B < A def foo(...) super(...) do |x| raise "should I be called?" end end end p B.new.foo { |x| x } # 3 ``` I'd expect Example 3 to raise an exception like Example 1. Additionally, I think the behavior in Example 2 is odd, but zsupers are "special" so I can understand if it is intended behavior. Is Example 3 intended behavior? If not, how should it behave? Thanks. -- https://bugs.ruby-lang.org/