Read in english (Automatic translate wiht Google)

Ao começar com Ruby várias coisas podem te deixar confuso. Como módulos, blocos, yield, proc, lambda e também a diferença entre load e require, include e extend. Então resolvi fazer essa pequena explicação para sanar a dúvida de quem estiver inciando em Ruby atualmente, pode ser que já exista um tutorial parecido por aí mas não me lembro de ter visto.

Require e Load

Em nosso exemplo, temos dois arquivos. require_exemplo1.rb e require_exemplo2.rb :

em require_exemplo1.rb

1
2
3
4
5

require 'require_exemplo2'

puts "meu nome é #{@name}"
puts "seu nome é #{SEUNOME}"
em require_exemplo2.rb
1
2
3

@name = "Daniel"
SEUNOME = "fulano"

Meu arq1.rb irá imprimir os valores de variável de instância (@name) e também a constante SEUNOME, pois basicamente o que o require faz é adicionar o código do arquivo requirido fazendo com que o arquivo que fez o require tenha acesso a este código após o require.

Agora vamos fazer o mesmo exemplo com load, criamos dois arquivos um chamado load_exemplo1 e outro load_exemplo2: em load_exemplo1.rb
1
2
3
4
5

load 'load_exemplo2.rb'

puts "meu nome é #{@name}"
puts "seu nome é #{SEUNOME}"
em load_exemplo2.rb
1
2
3

@name = "Daniel"
SEUNOME = "fulano"

Primeiro, ao usar o load precisamos especificar a extensão do arquivo. Fazendo isso o resultado será o mesmo que o com require. Mas a diferença não é só isso. Não vemos diferença pois este exemplo não é adequado.

Partindo para outro exemplo temos:

exemplo1.rb
1
2
3
4
5

puts "Passo 1"
require 'exemplo2'
puts "Passo 3"
require 'exemplo2'
exemplo2.rb
1
2

puts "Passo 2"

Ao executar teremos, impresso Passo 1 , Passo 2 e Passo 3 …. Passo 2 foi impresso pelo puts do meu arquivo exemplo2.rb mas mesmo eu requerendo ele novamente no final do exemplo1.rb ele não foi impresso novamente, pois require apenas requer o arquivo uma vez e não chama o código duas vezes. Mas se trocarmos o exemplo com abaixo:

exemplo1.rb
1
2
3
4
5

puts "Passo 1"
load 'exemplo2.rb'
puts "Passo 3"
load 'exemplo2.rb'
exemplo2.rb
1
2

puts "Passo 2"

Agora o resultado será Passo 1 Passo 2 Passo 3 Passo 2 …. o load irá chamar o código quantas vezes ele for carregado. Basicamente a diferença é esta. Require vai incluir o arquivo apenas uma vez enquanto o load irá incluir o arquivo quantos vezes ele for executado. O load é muito bom para arquivos que mudam em runtime enquanto o require será útil para arquivos que não serão alterados.

Include e Extend

E para que serve include e extend ?

Eles nada tem a ver com arquivos. Mas sim em como adicionar código em suas classes. Vejamos o exemplo abaixo:

Classe ruby.rb
1
2
3
4
5
6

module Ruby
  def shine
    "and shine"
  end
end 
Classe stone.rb
1
2
3
4
5
6
7
8

class Stone
  include Ruby
  
  def i_am
    "I am a rock"
  end
end

Então temos um modulo chamado Ruby, e uma classe chamada Stone… No arquivo da minha classe Stone(stone.rb) estou requerendo o arquivo ruby.rb que contém o módulo, então meu módulo passa a fazer parte do arquivo stone.rb mas ainda não faz parte da classe Stone. Então utilizo o include para embutir o módulo Ruby na classe Stone (esta ação é chamada de mixin)

Seu eu criar um instância de stone… terei acesso aos métodos do módulo e aos métodos da classe, veja abaixo:

1
2
3

my_stone = Stone.new
puts "#{my_stone.i_am} and #{my_stone.shine}" # =>I am a rock and shine

Agora já sabemos o que são requires, load, modules, mixin e include. Onde entra o extend? Vejamos o exemplo anterior com algumas alterações.

Classe ruby.rb
1
2
3
4
5
6

module Ruby
  def shine
    "and shine"
  end
end 
Classe stone.rb
1
2
3
4
5
6

class Stone
  def i_am
    "I am a rock"
  end
end

Continuo requerendo o arquivo ruby mas não faço mais o include, então minha classe ainda não tem o método shine. Mas depois de instaciar a classe Stone vou utilizar o extend, como abaixo:

1
2
3
4

stone = Stone.new
stone.extend Ruby
puts stone.shine

Desta forma estou adicinando o método shine apenas a instância stone mas se eu tivesse stone2 ela não teria acesso ao método shine.

Basicamente acho que estes exemplos ilustram bem as diferenças e quando usar, se eu tiver esquecido de alguma coisas por favor comentem abaixo. No próximo post sobre ruby vou tentar falar de yield, blocos, lambda e proc

4 Comentários to “Include,require,load e extend em Ruby”

  1. Flávio diz:

    Parabéns pelo texto, ficou bem claro as diferenças e as situações de uso para cada uma das funções. Ruby é uma linguagem muito poderosa, e é necessário conhecer bem esses conceitos para tirar o máximo de proveito.

    Abraço

  2. nofxx diz:

    Mto bacana, eu já nem lembrava mais de extend. Tipo um singleton require, hehe bem loco…

  3. Davis Zanetti Cabral diz:

    Muito legal o artigo.

    Só um detalhe: puts ”#{my_stone.i_am} and #{my_stone.shine}” # =>I am a rock and shine

    Vai imprimir: I am a rock and AND shine

    Abraço!

  4. Thiago Antonius diz:

    Opa, valeu pelo tutorial, praticamente não utilizo o load e o extend, como não utilizo nem sabia como os mesmos funcionavam. Obrigado pela explanação.

Deixe um comentário

If you can read this, you don't use a typical webbrowser that plays nice with CSS.
Please do not fill in anything here!