Ruby module: Include, Prepend and Extend

Tram Ho

The module must be an interesting and familiar feature for Ruby developers, you can use them to organize special functions and attach classes instead of using inheritance.

include is the most common way to import code from a module into a class, in addition Ruby provides two other ways to do this: extennd and prepend . Today’s article I will distinguish the difference when using 3 ways to import module code into class.

Ancestors chain

Provisional translation is the ancestral string (sounds a bit banana, so I would like to use the phrase ancestors chain)

When a class is created, it will have a list of ancestors – the name of the class it inherits, and the modules it imports. For example:

As we see this ancestor chain it will follow the order of inheritance and include. The first will be the MyClass class, and the end will be BasicObject – Ruby’s ancestor class. When searching for a called method, Ruby will search through each class in the order in this list, until found, then stop, or return the method missing if it has not found BasicObject.

Understanding the ancestors chain of the Ruby class, we can now compare the differences between the three methods of importing modules.

include

include is the simplest and most often used way when importing a module. When including a module in a class, Ruby adds this module to the ancestors chain of that class, immediately after that class, and before the superclass of that class.

For the example above, we can see that MyModule is inserted into the ancestors chain of MyClass right behind MyClass and in front of Object – the superclass of MyClass.

For example:

When we call obj.run , Ruby will perform a search for the my_method method in the ancestors chain of obj ‘s class C1. It will search from bottom to top and execute the first method found.

prepend

prepend is available from Ruby 2.0, but it seems less used than include and extend .

prepend works similarly to include , but the difference is where it is imported into the ancestors chain. When we prepend a module to a class, this module will be imported before that class in the ancestors chain.

extend

Unlike include and prepend , when using extend in a class the methods will be imported as class methods rather than instance methods.

If we use extend , the module that is extended to the class will not be added to the ancestors chain of that class. So we cannot call the methods in the module with objects of that class.

So when using extend, how will the module and class link together? Using extend Ruby will import the module’s methods into the ancestors chain of the singleton class of that class. Singleton classes are classes that contain singleton methods and class methods of an object (or a class). To understand the definition of singleton class, singleton method, you can search in viblo.

When the methods are imported into the singleton class, we can call those methods as class methods:

A common way for you to use a module that can import both class methods and instance methods is to use included

Through the article, I hope you understand the differences of the three methods of importing modules into the class that I mentioned.

Thank for your reading!

Reference article from: https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073

Share the news now

Source : Viblo