rubocop / rubocop/ruby-style-guide

`alias_method` should be preferred to `alias`

Open
#821 4 comments 15 reactions 1 assignee View on GitHub

@marcandre is already working on this.

Since Nov 23, 2020.

Approved
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:

See also this issue where @Ajedi32 puts forth similar arguments.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.