Alias in Ruby

By Mehdi Farsi

In the following article, we’re going to explore the following topics:

  • the alias keyword
  • the alias_method method
  • aliases and scopes
  • aliases behind the scene

Ruby provides an alias keyword to deal with method and attribute aliases

Here we define a User#fullname method and we define a username alias for this method.

Then, the username alias is aliased with a name alias.

So, a call to name or username will call the code defined within the User#fullname method and return the same result.

Note that it’s possible to define an alias for an existing alias.

The Module#alias_method method shares the same behavior as the alias keyword but it complies to the method syntax

Like the alias keyword, we define a User#fullname method and we define a username alias for this method.

Then the username alias is aliased with a name alias.

So, a call to name, username or fullname returns the same result.

We can see that the alias_method method takes a String or a Symbol as argument that allows Ruby to identify the alias and the method to alias.

If alias and Module#alias_method share the same behavior, then what’s the purpose of dealing with two things that do the exact same job?

The answer is that they don’t exactly do the same thing.

In effect, the Module#alias_method acts differently than the alias keyword on one specific point: the scope.

Let’s have a look to this example

Here we can see that the call to alias_method within the Device#alias_description method defines the describe alias on the Microwave#description method and not on the Device#description one.

Now let’s see what happens with the alias keyword

Here we can see that the call to alias within the Device#alias_description method sets the describe alias on the Device#description method and not on the Microwave#description one.

Let’s get back to the User class example to figure out what happens when an alias is defined

Behind the scene the username alias is treated as a method.

In effect, in Ruby each method is inserted in a table that keeps track of all the methods of your program. This table is called the method_entry table.

So, for the fullname method, a new entry is inserted in the method_entry table. This entry contains the following informations:

  • the :fullname method identifier
  • the content of the User#fullname method
  • the User class

Now, let’s have a look to the new entry for the username alias. This entry contains:

  • the :username method identifier
  • The content of the User#fullname method
  • the User class

That’s how the alias keyword and the alias_method method are able to define an alias for an existing method.

Note that an entry contains a way more informations than what I’ve described. But let’s keep it simple to focus on aliases.

Voilà!

In this article, we’re going to explore the following topics:

  • inheritance and the instance method
  • clone and dup methods
Have a look to the Part I (3-minutes read) before to read this article.

In the previous article we’ve seen that after including the Singleton module, an instance method is implicitly defined within the including class

Here, the Singleton module defines the Ebook.instance method when it’s included in the Ebook class.

Cool! But what happens if a RubyObjectModel class inherits from the Ebook class ?

In the above example, the RubyObjectModel class inherits from the Ebook class.

As the Ebook class includes the Singleton module, then a RubyObjectModel.instance class method is implicitly defined.

So, the RubyObjectModel class defines its own version of the instance method and doesn’t use the one defined in the Ebook class.

This freshly defined method returns a uniq RubyObjectModel instance — and not an Ebook instance.

This mechanism allows the RubyObjectModel class to inherit from the behaviors of the Singleton module and the Ebook class while dealing with an independent RubyObjectModel instance.

So the inheritance principle is not broken, while the singleton pattern is persisted through inheritance.

Ok, this is cool! But when inheriting from a class that includes the Singleton module can be useful?

Here, we define a base class named Client that encapsulate a bunch of common attributes as url, port and credentials.

After, we define the DBClient and ApiClient classes that derivate from the Client class.

As only one instance of these classes is required to coordinate actions across the program, then making them inheriting from the Client class seems to be a good decision.

In effect, with this pattern the DBClient and the ApiClient:

  • include the Singleton module
  • encapsulate common attributes
  • define common methods

When the Singleton module is included in a class then the Object#clone and Object#dup methods are overridden by the Singleton ones

In effect, these methods are redefined to raise an error.

This is due to the fact that, by essence, a uniq instance of a class shouldn’t be duplicable.

Feel free to read the Ruby Object Model article if you are unfamiliar with the Object class.

Otherwise, the Singleton module provides a clone class method that instantiate a new anonymous class.

Voilà !

Thank you for taking the time to read this post :-)

Feel free to 👏 and share this article if it has been useful for you. 🚀

Here is a link to my last article: redo keyword in Ruby.