Qual é a diferença entre include e require no Ruby?

Respostas:

543

Qual a diferença entre "incluir" e "exigir" no Ruby?

Responda:

Os métodos include e exigem fazem coisas muito diferentes.

O método require faz o que include faz na maioria das outras linguagens de programação: execute outro arquivo. Ele também rastreia o que você solicitou no passado e não exigirá o mesmo arquivo duas vezes. Para executar outro arquivo sem essa funcionalidade adicional, você pode usar o método de carregamento.

O método include pega todos os métodos de outro módulo e os inclui no módulo atual. Isso é uma coisa no nível do idioma, em oposição a uma coisa no nível do arquivo, como no require. O método include é a principal maneira de "estender" as classes com outros módulos (geralmente chamados de mix-ins). Por exemplo, se sua classe definir o método "each", você poderá incluir o módulo mixin Enumerable e ele poderá atuar como uma coleção. Isso pode ser confuso, pois o verbo incluir é usado de maneira muito diferente em outros idiomas.

Fonte

Portanto, se você quiser apenas usar um módulo, em vez de estendê-lo ou fazer um mix-in, será melhor usar require .

Curiosamente, Ruby requireé análogo ao C de include, enquanto Ruby includeé quase nada como C do include.

HanClinto
fonte
45
De fato, os Cs incluem, não carregam um arquivo conforme o necessário, mas substituem a linha #include pelo conteúdo do arquivo. Os arquivos incluídos não precisam ser 'cabeçalho' e #include não precisam estar no início do arquivo, mas podem estar em qualquer lugar, como na aula ou mesmo em uma definição de método. Isso significa que você pode mixar em C ++ gravando alguns métodos em um arquivo e incluí-lo no código de uma classe, exatamente como você faria em ruby. Portanto, eles não estão tão longe, mesmo que não seja uma prática comum nos C's.
MB14
13
Esta resposta pode se beneficiar ao incluir exemplos.
Urso Travis
12
O comentário do mb14 implica isso, mas é necessário declarar explicitamente: ao contrário do que a resposta diz, exigir não "executa" um arquivo, mas o carrega como se fosse parte do arquivo que o contém. Isso pode parecer nitpicking semântico, mas na verdade é uma diferença bastante importante.
Lonny Eachus
Ótima explicação. Obrigado por esclarecer a questão com a última declaração 'Por incrível que pareça, a exigência de Ruby é análoga à inclusão de C, enquanto a inclusão de Ruby é quase igual à inclusão de C'.
ArtSabintsev
1
@ GregSchmit: includeem Ruby é simplesmente herança. class C; include M endfaz Ma superclasse Ce a (antiga) superclasse da Csuperclasse de M. Não acho que C includefuncione por herança, acho que é uma simples substituição textual / lexical.
Jörg W Mittag
100

Se você estiver usando um módulo, isso significa que você está trazendo todos os métodos para sua classe. Se você é extenduma classe com um módulo, isso significa que você está "trazendo" os métodos do módulo como métodos de classe . Se você tem includeuma classe com um módulo, isso significa que você está "trazendo" os métodos do módulo como métodos de instância .

EX:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => método indefinido 'say' para B: Class

B.new.say => este é o módulo A

C.say => este é o módulo A

C.new.say => método indefinido 'say' para C: Class

Peter Dang
fonte
23
Eu acho que isso não responder à pergunta, mas é o que eu estava procurando =)
Ciro Santilli郝海东冠状病六四事件法轮功
2
Na verdade, isso não responde à pergunta sobre quais são as diferenças entre requiree includesão.
94

No livro Metaprogramming Ruby,

O require()método é bem parecido com load(), mas é para um propósito diferente. Você usa load()para executar código e require()para importar bibliotecas.

Pratik Khadloya
fonte
73
Upvote para não comparar para outro idioma na sua resposta :)
Stevo
Vote para não dar uma resposta no contexto da pergunta: "Se eu apenas quiser usar os métodos de um módulo na minha classe?"
benc
57
  • Ruby requireé mais parecido com "include" em outros idiomas (como C). Diz ao Ruby que você deseja trazer o conteúdo de outro arquivo . Mecanismos semelhantes em outros idiomas são:

  • Ruby includeé um mecanismo de herança orientado a objetos usado para mixins .

Há uma boa explicação aqui :

[A] resposta simples é que exigir e incluir são essencialmente independentes.

"require" é semelhante ao C include, o que pode causar confusão para iniciantes. (Uma diferença notável é que os locais dentro do arquivo necessário "evaporam" quando a solicitação é concluída.)

O Ruby include não é nada como o C include. A instrução include "combina" um módulo em uma classe. É uma forma limitada de herança múltipla . Um módulo incluído literalmente concede um relacionamento "é-a" à coisa que o inclui.

Enfase adicionada.

bradheintz
fonte
7

Você já tentou requireum módulo? Quais foram os resultados? Apenas tente:

MyModule = Module.new
require MyModule # see what happens

Módulos não podem ser necessários, apenas incluídos!

Boris Stitnicky
fonte
A afirmação aqui não está correta. Módulos podem ser necessários. E qualquer pessoa executando o código acima descobrirá que recebe o mesmo resultado ( TypeError) se a palavra Modulefor alterada para Class.
Pjd
7

De programação Ruby 1.9

Vamos fazer alguns pontos sobre a declaração de inclusão antes de prosseguirmos. Primeiro, não tem nada a ver com arquivos. Os programadores C usam uma diretiva de pré-processador chamada #include para inserir o conteúdo de um arquivo em outro durante a compilação. A instrução Ruby include simplesmente faz uma referência a um módulo. Se esse módulo estiver em um arquivo separado, você deverá usar o require (ou seu primo menos usado, load) para arrastar o arquivo antes de usar o include. Segundo, uma inclusão Ruby não copia simplesmente os métodos de instância do módulo para a classe. Em vez disso, faz uma referência da classe para o módulo incluído. Se várias classes incluírem esse módulo, todas apontarão para a mesma coisa. Se você alterar a definição de um método dentro de um módulo, mesmo enquanto seu programa estiver em execução,

cizixs
fonte
3

Incluir Quando você inclui um módulo em sua classe, como mostrado abaixo, é como se você pegasse o código definido no módulo e o inserisse na classe, onde você o inclui. Permite o comportamento 'mixin'. É usado para secar seu código para evitar duplicação, por exemplo, se houver várias classes que precisem do mesmo código dentro do módulo.

Carregar O método load é quase como o método require, exceto que não controla se a biblioteca foi carregada ou não. Portanto, é possível carregar uma biblioteca várias vezes e também ao usar o método de carregamento, você deve especificar a extensão “.rb” do nome do arquivo da biblioteca.

Exigir O método require permite carregar uma biblioteca e impede que ela seja carregada mais de uma vez. O método require retornará 'false' se você tentar carregar a mesma biblioteca após a primeira vez. O método require só precisa ser usado se a biblioteca que você está carregando estiver definida em um arquivo separado, o que geralmente é o caso.

Você pode preferir isso http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/

Sanket
fonte
3

Abaixo estão algumas diferenças básicas entre exigir e incluir:

Exigir:

  1. Exigir lê o arquivo do sistema de arquivos, analisa, salva na memória e executa-o em um determinado local, o que significa que, se você alterar alguma coisa enquanto o script estiver em execução, essa alteração não será refletida.
  2. Exigimos arquivo por nome, não por nome do módulo.
  3. É normalmente usado para bibliotecas e extensões.

Incluir:

  1. Quando você inclui um módulo em sua classe, ele se comporta como se você pegasse o código definido em seu módulo e o inserisse em sua classe.
  2. Nós incluímos o nome do módulo, não o nome do arquivo.
  3. Geralmente é usado para secar o código e remover a duplicação no código.
Awais Shafqat
fonte
2
require(name)

Ele retornará bolean verdadeiro / falso

O nome que é passado como parâmetro para o require, ruby ​​tentará encontrar o arquivo de origem com esse nome no caminho de carregamento. O método require retornará 'false' se você tentar carregar a mesma biblioteca após a primeira vez. O método require só precisa ser usado se a biblioteca que você está carregando estiver definida em um arquivo separado. Portanto, ele controla se essa biblioteca já foi carregada ou não.

include module_name

Suponha que você tenha alguns métodos que precisa ter em duas classes diferentes. Então você não precisa escrevê-los nas duas classes. Em vez disso, o que você pode fazer é defini-lo no módulo. E depois inclua este módulo em outras classes. É fornecido pelo Ruby apenas para garantir o princípio DRY. É usado para secar seu código para evitar duplicação

Shrinivas
fonte
2

Incluir

Quando você includeentra em um módulo em sua classe, é como se você pegasse o código definido dentro do módulo e o inserisse na classe, onde você o incluirá. Permite o comportamento 'mixin'. É usado para secar seu código para evitar duplicação, por exemplo, se houver várias classes que precisem do mesmo código dentro do módulo.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

Exigir

O método require permite carregar uma biblioteca e impede que ela seja carregada mais de uma vez. O método require retornará 'false' se você tentar carregar a mesma biblioteca após a primeira vez. O método require só precisa ser usado se a biblioteca que você está carregando estiver definida em um arquivo separado, o que geralmente é o caso.

Portanto, ele controla se essa biblioteca já foi carregada ou não. Você também não precisa especificar a extensão ".rb" do nome do arquivo da biblioteca. Aqui está um exemplo de como usar o require. Coloque o método require no topo do seu arquivo “.rb”:

Carga

O método load é quase como o método require, exceto que não controla se a biblioteca foi ou não carregada. Portanto, é possível carregar uma biblioteca várias vezes e também ao usar o método de carregamento, você deve especificar a extensão ".rb" do nome do arquivo da biblioteca.

Ampliar

Ao usar o método extend em vez de include, você está adicionando os métodos do módulo como métodos de classe em vez de como métodos de instância.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type
Imran Ahmad
fonte
2

'Load' - insere o conteúdo de um arquivo. (Analise o arquivo toda vez que o arquivo estiver sendo chamado)

'Exigir' - insere um conteúdo analisado pelo arquivo (arquivo analisado uma vez e armazenado na memória)

'Include' - inclui o módulo na classe e pode usar métodos dentro do módulo como método de instância da classe

'Estender' - inclui o módulo na classe e pode usar métodos dentro do módulo como método de classe

Vaishali Venkatesan
fonte