Include, Extend, And Prepend In Ruby
Introduction
Ruby provides a feature to attach a specific behaviour/methods in the classes using the keyword include
,extends
,
and prepend
. If we include a class with a module, it means we’re bringing in the module’s method as instance methods.
If we extend a class with a module method, it means we’re adding the methods which are added to class itself
and are available at class level. Prepending the module using prepend
is similar to the include.
Include
include
is the most common way of importing the module methods. When the module is called using the include
keyword
in a class, ruby inserts the module into the ancestors chain, after it’s super class.
1
2
3
4
5
```ruby
> MyClass.ancestors
=> [MyClass, ModuleOne, Object, .....]
```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
module ModuleOne
def hello
puts 'hello ModuleOne'
end
end
class MyClass
include ModuleOne
def greet
puts 'Good day !'
end
end
In above example, the ModuleOne
is included in the class. If we look the ancestor chain of MyClass we can see module
is present between the class and it’s ancestors. So, we can call methods defined in the class instances. For example
1
2
3
obj1 = MyClasse.new
obj1.hello # hello ModuleOne
Extend
In contrast to the include
, including a module using extend
doesn’t inserts the module in the ancestor chain.
Due to which we can’t call the module method from the Class instances. Instead, Ruby inserts the module in the
singleton class of the MyClass.The singleton class is a class where the methods only for the specific
class are defined. The methods defined in this class is not acessible to any other class or the instances.
An example of using the extend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module ModuleOne
def hello
puts 'hello ModuleOne for class'
end
end
class MyClass
extend ModuleOne
def greet
puts 'Good day !'
end
end
puts MyClass.hello # hello ModuleOne for class
puts Myclass.new.hello # error
Prepend
It is also similar to the include
, except that instead of inserting the module between the class and it’s superclass
in the chain, it will insert the module to the bottom which mean before it’s class itself. When we call
a method from a instance, it will look into the module method even before looking to it’s class.
An example of using the prepend
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
module ModulePrepend
def hello
puts 'hello ModulePrepend'
end
end
class MyClass
prepend ModulePrepend
def greet
puts 'Good day !'
end
end
obj = MyClass.new
obj.hello #hello ModulePrepend
In above example, when obj
calls the hello
method, it initially search the ModulePrepend
in the ancestor chain.
1
2
3
4
```ruby
> MyClass.ancestors
=> [ ModulePrepend, MyClass, Object, .....]
```