Include, Extend, And Prepend In Ruby

2 Min. Read
Aug 28, 2019

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, .....]
        ```