Alias methods in Ruby

I came across an interesting case where using Ruby’s method aliasing was really useful. If you’re not familiar with the alias functionality, the following example should explain it.

module Persona
  def name
    @name
  end
  
  def surname
    @surname
  end
  
  def full_name
    "#{name} #{surname}"
  end
end

class User
  include Persona
  
  def initialize(name,surname)
    @name,@surname = name,surname
  end
end

Here I am using a mixin to add functionality to the User class. If you’re unfamiliar with mixins, they’re a way to add a group of methods to a class. So in the example above, the include method will add all the methods from the Persona module to the User class – they will behave exactly as if they were defined on the User class. (This is the Ruby answer to multiple inheritance)

user = User.new("Jack","Ryan")
p "user.name: #{user.name}"
p "user.surname: #{user.surname}"
p "user.full_name: #{user.full_name}"

terminal output

The output probably explains it a bit better.

Now let’s say we want to make a slight change to the full_name method – for example, we want to return the full name, but in lowercase. One way of doing this would be to simply define a new full_name method on the User class.

def full_name
  "#{name} #{surname}".downcase
end

While this certainly works, it’s not a very good solution since it’s forcing us to redefine the entire method. This is obviously a very simple example, but what if the full_name method was actually something complex? What I would actually like to do is to reference the old method and replace it at the same time. (I could obviously define a separate full_name_lowercase method, but then I would need to update the calling code to use it)

It turns out Ruby actually allows us to reference the old method and still replace it – we simply need to use the alias_method method. This method takes 2 parameters – the name of the new alias and the method we want to be aliased.

class User
  include Persona
  
  def initialize(name,surname)
    @name,@surname = name,surname
  end
  
  alias_method :capitalized_full_name, :full_name
  
  def full_name
    capitalized_full_name.downcase
  end
end

If I run the previous code again, I get the desired result.

terminal output

What I really like about this approach is that I’m able to leverage off the existing method while still changing the functionality and there’s no need to change any of the calling code! Very cool.

There are two things to note about this approach. Firstly, the alias_method method accepts either strings or symbols. Secondly, there is also an alias method which does pretty much the same thing, except the functionality changes depending on scope and can be unpredictable at times. It seems the recommended approach is to use alias_method.

Real World Example

I came across this while working on a Rails project with a CoachDB database. The CouchRest library added a find_by_name method to the model, but it returned an array of records. In my case I knew that only one record would be returned, but since this method was outside my control I couldn’t change it. So instead of having to use SomeObject.by_name(name).first everywhere, I simply aliased the default method and then used it to always return the first record!

If you want to play around with this code you can grab my example here. Happy coding.