You can give an alternative name to a Ruby method in two ways:
- alias (keyword)
- alias_method
But why are there two ways to achieve a common goal? Let’s explore their differences to understand better!
The alias Keyword
First we have the alias , which is a Ruby keyword (like if , def , class , etc.) It looks like this:
1 2 3 | alias print_something puts print_something 1 |
Now calling print_something would be like calling puts
Alias has some interesting features as follows:
- It has a special syntax
- It can be used anywhere
- It is possible to alias global variables (But don’t do that)
Valid syntax:
1 2 3 4 5 6 | alias a b alias :a :b alias :"#{}" :b |
Note that there is no comma between arguments like in a regular method.
If you want to dynamic method names, you can do it like this …
1 2 3 4 5 | a = :print_something b = :puts alias :"#{a}" :"#{b}" |
The other looks bad, so you need to use alias_method to do this.
The alias_method Method
Next we have alias_method .
You cannot use this method in an instance method . It can only be definded within a class or module
Here is the description from the documentation:
alias_method: “Makes new_name a new copy of the method old_name. This can be used to retain access to methods that are overridden. ”
For example:
1 2 3 4 | class Foo alias_method :print_something, :puts end |
It will set alias for the puts method to print_something in the Foo class
You can also use strings as arguments instead of symbols
For example:
1 2 3 4 | class Foo alias_method "print_something", "puts" end |
alias vs alias_method
So when does the difference happen?
- When you want to create an alias with dynamically name (eg “abc # {rand}”)
- When you define alias inside a method
We saw how to use alias to create dynamic method name above, alias_method provides a more flexible syntax.
For example:
1 2 3 4 5 6 7 8 9 10 11 | class Cat def speak "meow" end alias_method "#{name.downcase}_speak", :speak end p Cat.new.cat_speak # "meow" |
However, as mentioned above, alias_method cannot be used inside a method, you will get the following error:
undefined method ‘alias_method’ for # (NoMethodError)
Here is a solution:
1 2 3 4 | def enable_aliased_methods self.class.send(:alias_method, :x, :testing) end |
However, using alias is much more concise
1 2 3 4 | def enable_aliased_methods alias :x :testing end |
So the biggest difference between them is:
- A method defined by the alias will belong to the class in which the alias is used
- A method defined by alias_method will belong to self , or the current class at the time the code is run
So what does this mean?
If you use alias in superclass then when you call alias in subclass you will call method in parent class
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Parent def method puts "parent" end # alias: alias :operation :method # alias_method: alias_method :operation, :method end class Child < Parent def method puts "children" end end # alias: Parent.new.operation => #parent Child.new.operation => #parent # alias_method: Parent.new.operation => #parent Child.new.operation => #children |
Aliasing Makes a Copy Of The Method
As described by alias_method & alias , Ruby creates a copy of the method, not just a copy of the method name.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 | def bacon 123 end alias :x :bacon x # 123 bacon # 123 |
Now that we’ve set alias x to bacon , let’s see what happens if we override bacon :
1 2 3 4 5 6 7 8 9 10 | def bacon 234 end x # 123 bacon # 234 |
bacon returns a new value and x does not.