-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add guideline about omitting super arguments #941
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3216,6 +3216,42 @@ def some_method(&) | |
end | ||
---- | ||
|
||
=== Super Forwarding | ||
|
||
Use `super` without arguments when the enclosing methods arguments are the same. | ||
|
||
When super is called without arguments and parentheses Ruby will automatically forward the arguments taken by the method. | ||
|
||
[source,ruby] | ||
---- | ||
# bad | ||
def some_method(*args, **kwargs) | ||
super(*args, **kwargs) | ||
end | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need an example with a named argument? Why are all examples splats? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why I made them all splats to be honest, there's no deeper meaning behind it. I can add a few more examples, though don't really see the reason. There's nothing special about splat/nonsplat and listing all possible variations is unnecessary imo., would just consistently use normal arguments instead. Wdyt? |
||
# good - implicitly passing all arguments | ||
def method(*args, **kwargs) | ||
super | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is blind forwarding, should we use the … syntax to describe parameters in the method signature? I understand that it is intent-revealing to write all of them. Won’t RuboCop with the default config suggest prefixing them with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RuboCop is smart enough to not raise an error here: the arguments are not unused |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do we dissect when to describe params in details, and when an unnamed splat ( |
||
# good - forwarding a subset of the arguments | ||
def method(*args, **kwargs) | ||
super(*args) | ||
end | ||
|
||
# good - calling super with different arguments | ||
def method(*args, **kwargs) | ||
super("foo", *args, **kwards) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven’t tried, but would There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does work in Ruby 3.1 (I think). |
||
end | ||
|
||
# good - forwarding no arguments | ||
def method(*args, **kwargs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, should this be _args and _kwargs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above |
||
super() | ||
end | ||
---- | ||
|
||
IMPORTANT: Blocks are always passed to the parent method. `&nil` can be passed to `super` if the block should remain local. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if there are other parameters? What is the recommended way to pass all arguments to super, but not the block? The … won’t work, will it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you don't want to pass the block you write Should I make a explicit example instead of just mentioning it here? |
||
|
||
=== Private Global Methods [[private-global-methods]] | ||
|
||
If you really need "global" methods, add them to Kernel and make them private. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m struggling to understand how this corresponds to the Arguments forwarding section above.
Both that other section and this new one have blind forwarding examples only. There, they suggest using the … syntax, and it is understandable. But only for the blind forwarding case.
But what about cases where only some of the arguments need to be forwarded? Like eg this one with
def m(foo, …)
? Does it even work?And moving on to the new addition. This all looks reasonable.
My only concerns are below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It fits thematically at least but I see your point about where I placed it. Perhaps it is better suited to come after "Using
super
with Arguments" ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My apologies for not expressing my thoughts clearly.
The place is right, I think this new section fits quite well under the arguments forwarding section, and it relates to it.
My concerns were more related to the existing “arguments forwarding” section, as its only “good example” is something I called “blind forwarding”, ie forwarding of all arguments.
This is not exactly always the case, and the existing section is incomplete and may even be confusing due to lack of coverage of those other cases with its only one good example.
Your addition, in the contrary, is detailed, and we happened to discuss a number of edge cases below, so it’s all good.
I’ll keep this comment open for a potential follow-up to improve the “arguments forwarding” section, but not in the scope of this PR.