
A Tale of 3 Aliases
In Ruby, we often want to rename methods or attributes for clarity, to extend functionality and for
compatibility. However, there are three different tools for this, each with its own use case and behavior: alias
,
alias_method
and alias_attribute
.
In this post we’ll go over each one of them, what they actually do and when to use them.
alias
alias
is a Ruby keyword. It creates a new name for an existing method or for a global variable
(avoid doing this, however). For methods, you can either use their names or symbols:
def old_name
"The old name"
end
alias new_name old_name
alias :new_name :old_name
# Or in the case of global variables. This isn't recommended.
alias $new $old
Note that, being a keyword, there is no comma between the names used with the alias keyword. alias
can also be used in any scope: inside instance methods, at class level or outside of classes and modules.
Additionally, alias
needs to be used with static values. To use dynamic names, we’d have to do something like:
new_name = "new_name"
old_name = "old_name"
alias :"#{new_name}" :"#{old_name}"
alias_method
alias_method
, on the other hand, is a method belonging to Module. It must be called within a module or
class (never inside instance methods) and the newly defined method will depend on what self
is at runtime:
class Foo
def puts
"Foo puts"
end
alias_method :print_something, :puts
end
Notice that we now use a comma, since it’s a method call. Furthermore, we can give alias_method
arguments
that wouldn’t work too well with alias
unless you employ certain workarounds:
class Foo
def numbers
"123"
end
alias_method "#{name.downcase}_numbers", :numbers
end
p Foo.new.foo_numbers
# "123"
alias_attribute
Finally, we have alias_attribute
. This is actually a Rails convenience method. Fundamentally the semantics
are the same as for alias
and alias_method
, but alias_attribute
has a very specific use case which is
to allow us to alias model attributes in Rails, which implies it aliases getters, setters and question methods
for the model:
class Transaction < ApplicationRecord
alias_attribute :amount, :value
end
transaction = Transaction.new
transaction.value? # will work
transaction.amount? # will work now as well
This is useful, for example, when you need a database column and the corresponding ActiveModel methods to have different names, either because you intend to change the database structure or because the semantics are better this way.
Which one to pick?
Given all that, which one to use?
alias_attribute
is clearly only applicable to the specific case of ActiveModel attributes.
Now the choice between alias
and alias_method
will depend largely on the scope you need to apply the alias.
alias
and alias_method
both make new copies of the methods. alias_method
, however creates the new copy
on the object that calls it on runtime, whereas alias
will create the new copy where it’s defined. To illustrate:
class Car
def start
p "Vrum"
end
def create_alias
alias :turn_on :start
end
end
class Mustang < Car
end
mustang = Mustang.new.create_alias
car = Car.new
car.turn_on # "Vrum"
mustang.turn_on # NoMethodError
If we use alias_method
, however:
class Car
def start
p "Vrum"
end
alias_method :turn_on, :start
end
class Mustang < Car
end
mustang = Mustang.new
car = Car.new
car.turn_on # "Vrum"
mustang.turn_on # "Vrum"
And, more interestingly:
class Car
def start
p "Vrum"
end
end
class Mustang < Car
alias_method :turn_on, :start
end
mustang = Mustang.new
car = Car.new
mustang.turn_on # "Vrum"
car.turn_on # NoMethodError
In the very first example, alias
was called at runtime by an instance of Mustang
, however, we got an
error when we attempted to call turn_on
on that instance. This shows that alias
will create the new
method’s copy on the class where it’s stated.
Inversely, alias_method
will create the new copy in the class that actually calls it at runtime. Once we
moved it to the Mustang
class, we got an error when we tried to call turn_on
on an instance of Car
,
since the alias was made on the Mustang
class.
Summary
alias
:- Ruby keyword
- Can be used in any scope. Won’t accept dynamic names unless we use specific workarounds
- This should be the default, unless you want more flexibility or want scope to be restricted
alias_method
:- Method provided by Ruby’s
Module
- Can accept dynamic arguments but must be used at the class or module level
- Use this if you want to restrict scope and want to be able to easily provide dynamic arguments
- Method provided by Ruby’s
alias_attribute
:- Rails helper from ActiveSupport
- Use when you need to alias model attributes in Active Record
Each of them is useful in their own context, so choose the one that best fits your needs.
Need help with your Rails application? Whether it’s general maintenance, upgrading or feature development, talk to us!