— Feb 23, 2016
A quick post about when I choose to alias methods in Ruby, and when I don’t.
If you have programmed Ruby at all, you have probably noticed that there are a lot of ways to do one thing.
For example, to raise an error, you can use the
raise method or you can use the
Both have exactly the same behavior.
In fact, they are exactly the same thing.
If you check out the docs for
fail, you’ll see…
So why have it?
Ruby provides us with the ability to choose the method that best communicates intent.
The late Jim Weirich had a somewhat well known semantic for
He would use
fail for irrecoverable errors (or… failures), and he would use
raise for errors that may be caught elsewhere.
Avdi Grimm was kind enough to capture Jim’s opinion in a post.
There are a number of other examples throughout the Ruby codebase, e.g. Enumerable#inject and Enumerable#reduce.
It’s all in the name of writing self-evident code.
In short, alias a method when the new method you’re exposing is literally another word for the same thing. Let’s check out an example.
Here’s a snippet of code that was recently discussed in code review.
class Foo def part locate end private def locate # some part locating logic end end
The comment came on the implementation of
Why not just
alias_method :part, :locate?
It makes sense, the entire implementation of
part is literally calling another method.
So save a couple lines and make it an alias, right?
This introduces a cognitive “WAT”.
part method an alias of
locate states that it literally carries the same semantic meaning as
These two methods actually have two distinct purposes.
part- expose a public interface on
Foofor getting its
locate- do something to find the
This becomes especially apparent when a new requirement comes in.
Optimize Foo#part by memoizing the located value.
If you had aliased
locate, you would now be ripping that out to implement an actual
def part - locate + @part ||= locate end
Beyond this practical advantage, there is also cognitive gain. You know at a glance of the class that “Foo has a part” rather than “Apparently Foo’s locate is also known as a part” (???).
Assume that you have shipped
It’s out in the wild and a number of other’s depend on the fact that
Foo has a
However, you decide that
part isn’t the best name for this data member.
You want to refer to it as
def part @part ||= locate end +alias_method :widget, :part
The reader of your code immediately recognizes that
widget is just another name for
But please do consider a deprecation message.