Bug #20392
closedDelegate super calls with a block
Description
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:
# 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:
# 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.
Updated by Dan0042 (Daniel DeLorme) 9 months ago
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.
Updated by jeremyevans0 (Jeremy Evans) 9 months ago
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.
Updated by tenderlovemaking (Aaron Patterson) 9 months ago
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 asfoo(...){}
is.
super
behavior in general is special. For example,super(arg)
is not a zsuper, but still passes the block implicitly, you have to dosuper(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.
Updated by jeremyevans0 (Jeremy Evans) 9 months ago
tenderlovemaking (Aaron Patterson) wrote in #note-3:
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)
It's missing entries for NODE_SUPER
and NODE_ZSUPER
in get_nd_args
, so the nd_args
are ignored for those nodes. At least those node types should be fixed, and all other node types in the switch should be checked to see if this isn't swallowing other syntax errors. @yui-knk (Kaneko Yuichiro) is my analysis correct?
Updated by nobu (Nobuyoshi Nakada) 9 months ago
- Description updated (diff)
Updated by nobu (Nobuyoshi Nakada) 9 months ago
jeremyevans0 (Jeremy Evans) wrote in #note-4:
It's missing entries for
NODE_SUPER
andNODE_ZSUPER
inget_nd_args
, so thend_args
are ignored for those nodes. At least those node types should be fixed, and all other node types in the switch should be checked to see if this isn't swallowing other syntax errors. @yui-knk (Kaneko Yuichiro) is my analysis correct?
I think that zsuper is special.
Updated by nobu (Nobuyoshi Nakada) 9 months ago
- Status changed from Open to Closed
Applied in changeset git|a850cd1a87bef738c40d9c550fb8823699083f2e.
[Bug #20392] Block arguments duplication check at super