Accessing a module at the root of another file in Ruby

Juzer Shakir
4 min readJul 14, 2021

A deep look into how and which methods are available for a module when it's accessed from another file.

Prerequisite

This topic will be easier to comprehend if you have knowledge of the following:

If you want to know how to call a module to access its methods in a class, refer to this article 👉 Module in Ruby .

Topics covered in this article

One of the key features of a module is that you can access its methods, constants, and classes in a different program by just importing the module instead of re-writing the logic, preventing the violation of the DRY (Do not Repeat Yourself) concept.

Our Module whose methods need to be imported to another file

To access the module from a file, first, we need to access the file by require_relative keyword followed by file_name of a module that has to be imported.

Next, we need to import the module, we have 2 ways to do this, either by extend or include keywords.

Both extend and include descend from Class Module, which is the parent of class Class.

Accessing Module methods with extend keyword:

  1. We cannot access the instance methods through the module Test::Hello.

Accessing Module methods with include keyword:

Raw Code
  1. We can access the instance methods through the module Test::Hello.

The module methods & instance methods can be accessed by both extend & include keyword.

Regardless of which keyword you use extend or include :

  1. the only way to access the module methods is by Module_name::method_name

2. The instance methods can be accessed by method name alone, for ex. the hello method.

To study why there are these subtle differences, we need to take a look at the hierarchy chain:

include:

Raw Code

By looking at the ancestor chain we can conclude that the module Test is available as a parent of the class Object.

When the method hello is not found in the Class C_test, it scans inside the parent class Object, it cannot find there too, and then scans in the grandparent module Test and eventually, it will find there.

Ruby includes Kernel module inside the Class Object and then we explicitly define include Test module in our root program, so now we have 2 modules that are included in the Class Object, Kernel & Test.

extend:

Raw Code

extend keyword brings instance methods of the Test module, as an instance method to the singleton class of an instance of a class Object.

In other words,

extend keyword brings instance methods of a Module as the singleton methods of an instance of a class Object.

Normally when using the extend keyword inside a class, the instance methods of a module would be accessible as singleton methods to the class it's defined in, but not in this case as we are declaring it outside the class or in other words in an instance of the class Object.

Therefore, hello isn’t not a singleton/class method of class Object but an instance of the class Object, and this instance is created by Ruby when any program initiates.

To better understand these above statements:

Notice the output of singleton_methods in both cases above, this proves our point!

The reason why the hello method works for both the include and extend keyword is because the instance of the class Object is initialized automatically by Ruby at the time of execution and when we include or extend a module in our program, ruby will automatically load the hello method. And this goes true for any instance methods inside the module we define.

hello  # => I'm an instance method

Any suggestions or edits in the article are always welcome! Thank you!

My previous article: Modules in Ruby

GitHub | LinkedIn

--

--