Accessing a module at the root of another file in Ruby
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 .
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.
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:
- We cannot access the instance methods through the module
Test::Hello
.
Accessing Module methods with include
keyword:
- 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
:
- 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:
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
include
sKernel
module inside the ClassObject
and then we explicitly defineinclude Test
module in our root program, so now we have 2 modules that are included in the ClassObject
,Kernel
&Test
.
extend:
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 classObject
but an instance of the classObject
, 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