You can give an alternative name to a Ruby method in two ways:
- alias (keyword)
- alias_method
Because they do the same thing in slightly different ways this can be a confusing topic.
This image is a summary of the differences:
Let’s explore these differences in more detail to get a solid understanding!
The alias Keyword
First we have alias
, which is a Ruby keyword (like if
, def
, class
, etc.)
It looks like this:
alias print_something puts print_something 1
Now calling print_something
is the same as calling puts
.
Because alias
is a keyword it has some interesting attributes:
- It has special syntax
- It can be used anywhere in your code
- It can alias global variables (don’t do this!)
The valid forms of alias are:
- alias a b
- alias :a :b
- alias :”#{}” :b
Notice that there are no commas between the arguments like in a regular method.
Ruby expects both a
& b
to be valid method names, variables don’t work here. If you want to use variables you’ll have to do something like this…
Example:
a = :print_something b = :puts alias :"#{a}" :"#{b}"
But this looks ugly, so you may want to use alias_method
for dynamic method names.
The alias_method Method
Next:
We have alias_method
, which is a method defined on Module
.
You can only use this method at the class & module level, but not inside instance methods.
Here’s a description from the documentation:
alias_method: “Makes
new_name
a new copy of the methodold_name
. This can be used to retain access to methods that are overridden.”
Example:
class Foo alias_method :print_something, :puts end
This will alias print_something
to puts
inside Foo
.
You can use strings as alias_method
arguments.
Example:
class Foo alias_method "print_something", "puts" end
alias vs alias_method
You’ve seen an overview of alias
& alias_method
.
But when do the differences come into play?
- When you define an alias for a dynamically generated method name (like “abc#{rand}”)
- When you define an alias inside a method
Defining an alias for a dynamically generated method name is possible with the alias
keyword but you have to use interpolated symbols.
With alias_method
you get more flexible arguments.
Example:
class Cat def speak "meow" end alias_method "#{name.downcase}_speak", :speak end p Cat.new.cat_speak # "meow"
Now:
If you want to define an alias inside a method you’ll get this error:
undefined method 'alias_method' for # (NoMethodError)
Because you’re working within an object & not a class!
Inside an instance method you don’t have access to methods defined in Module
, which is where alias_method
is defined.
Here’s one possible solution:
def enable_aliased_methods self.class.send(:alias_method, :x, :testing) end
Using alias
:
def enable_aliased_methods alias 😡 :testing end
One important difference:
- A method defined by
alias
will belong to the class wherealias
is used - A method defined by
alias_method
will belong toself
, the current class at the time the code is run
This is why that matters:
If you call a method on a parent class that uses the alias
keyword…
The aliasing will happen on the parent class & not on the class that’s calling the method.
Example:
class Food def create_alias alias print_on_screen puts end end class Apple < Food end Apple.new.create_alias
But if you use alias_method
the method will only be aliased on Apple
.
Aliasing Makes a Copy Of The Method
As per the description of alias_method
& alias (keyword)
, Ruby creates a copy of the method.
It’s not only a new name.
But an actual copy of the method.
This has some practical implications:
def bacon 123 end alias 😡 :bacon x # 123 bacon # 123
So we alias x
to bacon
, now watch what happens if I redefine bacon
:
def bacon 234 end x # 123 bacon # 234
The x
method stays the same, but bacon
returns the new value!
This can come as a surprise if you’re including modules to your class after aliasing methods.
Video Tutorial
Summary
In general I like more alias_method
because it’s an actual method.
While the alias
keyword has some special attributes that you have to remember & keep in mind.
Did you learn something new?
Share this article with your Ruby friends so they can learn too!