---
tags: minimeet, Ruby
---
I found `prepend` method while writing `EventService`, which is not mentioned as often as `include` or `extend`, so I sorted out the differences between these three.
# Ruby Include, Extend and Prepend
> references:
> [Ruby modules: Include vs Prepend vs Extend](https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073)
> [Include, Extend, And Prepend In Ruby](https://veerpalbrar.github.io/blog/2021/11/26/Include,-Extend,-and-Prepend-In-Ruby)
> [Eigenclasses](https://gorails.com/episodes/eigenclasses?autoplay=0)
> [The Ruby Object Model by Dave Thomas](https://www.youtube.com/watch?v=X2sgQ38UDVY&list=PLB-QUC_lHBYN1yBjWcRf9YLNv3UDZIoxc&index=10)
Here we have a module `Instinctive` which has a instance method called `eat`, and a class named `Human` for the later examples.
```ruby
module Instinctive
def eat
p "#{name} is eating..."
end
end
class Human
attr_reader :name
def self.eat
p 'Human class can eat'
end
def initialize(name)
@name = name
end
def eat
p 'Human instance can eat'
end
end
```
## include
`include` might be the most common way that we used.
And we know that `include` adds methods as instance methods.
for example:
```ruby
class Male < Human
include Instinctive
end
johnny = Male.new(:johnny)
johnny.eat
# => "johnny is eating..."
```
As we can see, the `eat` method was called from `Instinctive` instead of `Hunam`.
That is because `include` adds `Instinctive` between `Male` and `Human` in the ancestors chain.
```ruby
Male.ancestors
# => [Male, Instinctive, Human, Object...]
```

Ruby found `eat` in `Instinctive` before `Human`, so it stopped and invoked it.
## extend
Unlike `include`, `extend` acts like class methods.
It adds methods as `singleton_methods` to `Female`.
```ruby
class Female < Human
extend Instinctive
end
jenny = Female.new(:jenny)
jenny.eat
# => "Human instance can eat"
Female.eat
# => "Female is eating..."
```
Let's see the ancestors chain of `Female`.
```ruby
Female.ancestors
# => [Female, Human, Object...]
```
`Instinctive` was not added to this chain, but `eat` added to `Female`
```ruby
Female.singleton_method
# => [:eat]
```

## prepend
`prepend` will be added into ancestors chain like `include`, but in the opposite way.
```ruby
class Baby < Human
prepend Instinctive
end
alex = Baby.new(:alex)
alex.eat
# => "alex is eating.."
```
It looks like what `include` did so far, but if we dig into the ancestors chain, you'll find out `Instinctive` was added before `Baby`
```ruby
Baby.ancestors
# => [Instinctive, Baby, Human, Object...]
```

## super
There is one thing that we need to notice is the usage of `super`
`Instinctive` is an ancestor of `Male`, so we can invoke `super` inside `Male`
```ruby
class Male
def eat
super
p "#{name} does not like it"
end
end
johnny = Male.new(:johnny)
johnny.eat
# => "johnny is eating..."
# => "johnny does not like it"
```
`Baby` is the ancestor of `Instinctive`, so we need to invoke `super` inside `Instinctive`
```ruby
module Instinctive
def eat
super
p "#{name} is eating..."
end
end
class Baby
def eat
p "#{name} was hungry"
end
end
alex = Baby.new(:alex)
alex.eat
# => "alex was hungry"
# => "alex is eating..."
```