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
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
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
18/09/2008 em 01:17 PM
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
18/09/2008 em 01:17 PM
Mto bacana, eu já nem lembrava mais de extend. Tipo um singleton require, hehe bem loco…
18/09/2008 em 02:01 PM
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!
30/09/2008 em 03:06 PM
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.