rubocop / rubocop/ruby-style-guide
`alias_method` should be preferred to `alias`
@marcandre is already working on this.
Since Nov 23, 2020.
- Dominant language
- No language data
- Stars
- 16.5k
- Forks
- 3.3k
- PR merge metrics
- No merged PRs in 30d
Description
TLDNR: The styleguide and RuboCop should always prefer the use of alias_method.
Obscure difference
Ask 100 Rubyists to provide an example where alias and alias_method act differently. I would be surprised if a single one was able to.
I admit I couldn't. My friend and co-author of DeepCover couldn't.
The example given in the style guide isn't a good one either (use alias and it works in the same way).
I had to look it up
alias sometimes wrong, sometimes not possible, alias_method always works
The style guide admits that alias can be confusing in some cases and thus says to use it in other contexts.
It is implicitly admitted that there is never a case where alias actually does something better than alias_method does.
alias also doesn't accept a receiver, or variable arguments
invalid reasons
The reason given in the guide is:
Prefer alias when aliasing methods in lexical class scope
Please ask 100 rubyists what is a "lexical class scope".
as the resolution of self in this context
It is not the resolution of self, but the resolution of the "currently opened class". The self is never lexical. Take the example of the blog, wrap the alias in a instance_eval and things remain the same. Wrap it instead in a class_eval and things work; both change the self (here doing nothing as the receiver is self) but they affect the "currently opened class" differently. I find it quite obscure.
is also lexical
How is that an advantage? In these cases, the self and the currently opened class are always the same anyways. The existence of attr_reader, etc., make it such that we are used to think about the current self way more than the current open class.
and it communicates clearly to the user that the indirection of your alias will not be altered at runtime or by any subclass unless made explicit.
IIC, the idea behind the rule is that only uses of alias_method can affect a subclass (say within a def self.inherit?) and that alias won't since its usage is restricted to the simple cases. If so... why is that of any importance? When is that really a concern? When is it not obvious that an alias_method is impacting another class than the current class?
Complicated "when to apply"
Asking Rubyists to sometimes use alias and sometimes use alias_method overcomplicates things for no gain.
It makes some refactorings awkward:
class MyClass < Struct.new(:foo)
alias foo? foo
def bar
end
end
# Refactored to:
MyClass = Struct.new(:foo) do
alias_method :foo?, :foo # How is that meaningfully different?
def bar
end
end
Note: I'm not sure at all what a "lexical class scope" means, I'm assuming that RuboCop's cop is correct here.
In short, I feel that alias was a language design mistake, an unnecessary keyword that is best avoided.
Any rule that attempts to distinguish when to use one or the other adds a complex cognitive load and will make distinctions when there aren't (as in example above). Note that a rule that would say "use alias unless alias_method acts differently" would not make unnecessary distinctions (by definition) but then falls under the "so complex that nobody knows when to apply it".
The one rule
The rule "always prefer alias_method" is straightforward, always applicable and can not be simpler. It should be the official rule of this guide and the default of RuboCop.
I will gladly provide a PR to fix this guide and RuboCop if it is accepted.
Notes:
- Github's styleguide as well as most guides derived from it (like AirBnB's) prefer
alias_method - Shopify's styleguide prefers
alias_method - The author of the blog post above prefers
alias_method - The most highly rated answer on StackOverflow prefers
alias_method
See also this issue where @Ajedi32 puts forth similar arguments.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.