What’s the difference between "include" and "extend" in Ruby?

Asked

Viewed 572 times

1

I’m studying Ruby, and I’ve come to realize that there are two ways (maybe there are more) of injecting methods into a class. At first I thought they might be the same things, since Ruby is a language that aims to be quite flexible for programmers.

However, I just attended a class where the teacher explained about hook and the methods self.included, self.extended and self.inherited, and it made me think: "Do these two forms below really have no difference at all ? "

Using the include:

class MinhaClasse
    include Modulo
end

Using the extend:

class MinhaClasse
    extend Modulo
end

Is there any difference between using the extend and include ? If yes what is the difference and when I should use each of them ?

1 answer

1


The difference is that the include injects the methods of a module into a class or another module such as instance methods. Already the extend, injects them as class methods. Still having doubts about these two guys ? Let’s see an example then :-)

To serve as an example, we will create a module called TestModule that will have a method called hello:

module TestModule
    def hello
        puts "Hello World!"
    end
end

Now let’s create an empty class and use the include to add the method.

class Test
    include TestModule
end

Test.new.hello  # Não gera erro
Test.hello      # Gera erro

By executing this code, we can see that the method is called and the message is printed perfectly, but soon after this error is released:

Undefined method `hello' for Test:Class (Nomethoderror)

This happens because we define the method hello to be a instance method and in the last line we try to call the method as if it were a class method. Now let’s test the same code, only this time using the extend.

class Test
    extend TestModule
end

Test.hello      # Não gera erro  (eu troquei a ordem das linha para o erro ser gerado depois)
Test.new.hello  # Gera erro

As in the previous example, in this code the message "Hello World!" is printed and immediately after an error is generated:

Undefined method `hello' for # Test:0x000004dfe090 (Nomethoderror)

If you notice correctly, the two error messages are different. This is because in the first example, there was no class method (the error message shows that we try to call a method of Test:Class) called hello.

In the second example, there was no instance method (the error message shows that we tried to call a method of <Test:0x0000000004dfe090>) called hello.


Summing up:

Include: Injects the methods to be called with an instance. (Test.new.hello)

Extend: Injects the methods to be called with the class. (Test.hello)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.