A Tale of 3 Aliases

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}"

Docs opens a new window

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"

Docs opens a new window

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.

Docs opens a new window

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
  • 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! opens a new window

Get the book