Qual'è la differenza tra include e require in Ruby?


Risposte:


543

Qual è la differenza tra "includi" e "richiedi" in Ruby?

Risposta:

I metodi include e richiedono fanno cose molto diverse.

Il metodo Require fa ciò che include nella maggior parte degli altri linguaggi di programmazione: eseguire un altro file. Tiene traccia anche di ciò che hai richiesto in passato e non richiederà lo stesso file due volte. Per eseguire un altro file senza questa funzionalità aggiunta, è possibile utilizzare il metodo di caricamento.

Il metodo include prende tutti i metodi da un altro modulo e li include nel modulo corrente. Questa è una cosa a livello di lingua al contrario di una cosa a livello di file che richiede. Il metodo include è il modo principale per "estendere" le classi con altri moduli (di solito chiamati mix-in). Ad esempio, se la tua classe definisce il metodo "ciascuno", puoi includere il modulo Mixin Enumerable e può fungere da raccolta. Questo può essere fonte di confusione poiché il verbo include è usato in modo molto diverso in altre lingue.

fonte

Quindi, se vuoi semplicemente usare un modulo, piuttosto che estenderlo o fare un mix-in, allora vorrai usare require.

Stranamente, Ruby requireè analoga a C del include, mentre Ruby includeè quasi niente come C di include.


45
In effetti, C include, non carica un file come richiesto, ma sostituisce invece la riga #include, con il contenuto del file. I file inclusi non devono essere "header" e #include non devono essere all'inizio del file, ma possono trovarsi ovunque, come in classe o persino una definizione di metodo. Questo significa che puoi fare mixin in C ++ scrivendo alcuni metodi in un file e includendolo nel codice di una classe, esattamente come faresti in ruby. Quindi non sono così lontani, anche se in effetti non è una pratica comune in C.
mb14

13
Questa risposta potrebbe trarre beneficio dall'inclusione di esempi.
Orso Travis,

12
Il commento di mb14 implica questo, ma porta esplicitamente a dichiarare: contrariamente a quanto dice la risposta, richiede non "esegue" un file, ma piuttosto lo carica come se fosse parte del file contenente. Potrebbe sembrare un nitpicking semantico, ma in realtà è una differenza piuttosto importante.
Lonny Eachus,

Ottima spiegazione Grazie per aver portato il punto a casa con l'ultima affermazione "Stranamente, il requisito di Ruby è analogo all'inclusione di C, mentre l'inclusione di Ruby è quasi nulla come l'inclusione di C."
ArtSabintsev

1
@GregSchmit: includein Ruby è semplicemente eredità. class C; include M endcrea Mla superclasse di Ce la (ex) superclasse di Csuperclasse di M. Non penso che C includefunzioni per eredità, penso che sia una semplice sostituzione testuale / lessicale.
Jörg W Mittag,

100

Se stai usando un modulo, significa che stai portando tutti i metodi nella tua classe. Se sei extenduna classe con un modulo, significa che stai "portando" i metodi del modulo come metodi di classe . Se sei includeuna classe con un modulo, significa che stai "portando" i metodi del modulo come metodi di istanza .

EX:

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

 class B
   include A
 end

 class C
   extend A
 end

B.say => metodo non definito 'dire' per B: Classe

B.new.say => questo è il modulo A

C.say => questo è il modulo A

C.new.say => metodo non definito 'say' per C: Class


23
Penso che questo non risponda alla domanda, ma è quello che stavo cercando =)
Ciro Santilli 29 冠状 病 六四 事件 法轮功

2
Questo in realtà non risponde alla domanda su quali siano le differenze tra requiree include.

94

Dal libro Ruby sulla metaprogrammazione,

Il require()metodo è abbastanza simile load(), ma è pensato per uno scopo diverso. Utilizzi load()per eseguire il codice e require()per importare le librerie.


73
Voto per non confrontare con un'altra lingua nella tua risposta :)
Stevo

Votazione negativa per non aver fornito una risposta nel contesto della domanda: "Se voglio solo usare i metodi di un modulo nella mia classe?"
benc

57
  • Ruby requireè più simile a "include" in altre lingue (come C). Indica a Ruby che vuoi portare il contenuto di un altro file . Meccanismi simili in altre lingue sono:

  • Ruby includeè un meccanismo di ereditarietà orientato agli oggetti utilizzato per i mixin .

C'è una buona spiegazione qui :

[La] risposta semplice è che richiedono e includi sono essenzialmente indipendenti.

"request" è simile al C include, che può causare confusione ai principianti. (Una differenza notevole è che i locali all'interno del file richiesto "evaporano" quando il requisito è completato.)

Il Ruby include non è come il C include. L'istruzione include "mescola" un modulo in una classe. È una forma limitata di eredità multipla . Un modulo incluso conferisce letteralmente una relazione "is-a" sulla cosa includendolo.

Enfasi aggiunta.


7

Hai mai provato requireun modulo? Quali sono stati i risultati? Prova:

MyModule = Module.new
require MyModule # see what happens

I moduli non possono essere richiesti, inclusi solo!


L'asserzione qui non è corretta. I moduli possono essere richiesti. E chiunque esegua il codice sopra troverà che riceverà lo stesso risultato ( TypeError) se la parola Moduleviene cambiata in Class.
pjd

7

Dalla programmazione di Ruby 1.9

Faremo un paio di punti sulla dichiarazione include prima di continuare. Innanzitutto, non ha nulla a che fare con i file. I programmatori C usano una direttiva preprocessore chiamata #include per inserire il contenuto di un file in un altro durante la compilazione. L'istruzione include di Ruby fa semplicemente riferimento a un modulo. Se quel modulo si trova in un file separato, devi usare il comando (o il suo cugino meno comunemente usato, caricare) per trascinare quel file prima di usare include. In secondo luogo, un'inclusione di Ruby non copia semplicemente i metodi di istanza del modulo nella classe. Invece, fa un riferimento dalla classe al modulo incluso. Se più classi includono quel modulo, indicheranno tutte la stessa cosa. Se modifichi la definizione di un metodo all'interno di un modulo, anche mentre il tuo programma è in esecuzione,


3

Includi Quando includi un modulo nella tua classe come mostrato di seguito, è come se prendessi il codice definito all'interno del modulo e lo inserissi nella classe, dove lo 'includi'. Permette il comportamento 'mixin'. Viene utilizzato per ASCIUGARE il codice per evitare la duplicazione, ad esempio, se vi fossero più classi che avrebbero bisogno dello stesso codice all'interno del modulo.

Carica Il metodo di caricamento è quasi come il metodo request tranne che non tiene traccia del caricamento o meno della libreria. Quindi è possibile caricare una libreria più volte e anche quando si utilizza il metodo load è necessario specificare l'estensione ".rb" del nome del file della libreria.

Require Il metodo Require consente di caricare una libreria e ne impedisce il caricamento più di una volta. Il metodo request restituirà 'false' se si tenta di caricare la stessa libreria dopo la prima volta. Il metodo Requisito deve essere utilizzato solo se la libreria che si sta caricando è definita in un file separato, come di solito accade.

Puoi preferire questo http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/


3

Di seguito sono riportate alcune differenze di base tra richiedono e includono:

Richiedere:

  1. Require legge il file dal file system, lo analizza, lo salva nella memoria e lo esegue in un determinato posto, il che significa che cambierai anche qualcosa mentre lo script è in esecuzione di quanto la modifica non rifletterà.
  2. Richiediamo il file per nome, non per nome del modulo.
  3. In genere viene utilizzato per librerie ed estensioni.

Includere:

  1. Quando includi un modulo nella tua classe, si comporta come se prendessi il codice definito nel tuo modulo e lo inserissi nella tua classe.
  2. Includiamo il nome del modulo, non il nome del file.
  3. In genere viene utilizzato per prosciugare il codice e rimuovere la duplicazione nel codice.

2
require(name)

Restituirà bolean vero / falso

Il nome che viene passato come parametro al requisito, ruby ​​proverà a trovare il file di origine con quel nome nel percorso di caricamento. Il metodo request restituirà 'false' se si tenta di caricare la stessa libreria dopo la prima volta. Il metodo request deve essere utilizzato solo se la libreria che si sta caricando è definita in un file separato. Quindi tiene traccia del fatto che quella libreria sia già stata caricata o meno.

include module_name

Supponiamo che tu abbia alcuni metodi che devi avere in due classi diverse. Quindi non devi scriverli in entrambe le classi. Invece quello che puoi fare è definirlo nel modulo. E quindi includere questo modulo in altre classi. È fornito da Ruby solo per garantire il principio DRY. Viene utilizzato per ASCIUGARE il codice per evitare la duplicazione


2

Includere

Quando fai includeun modulo nella tua classe, è come se prendessi il codice definito all'interno del modulo e lo inserissi all'interno della classe, dove lo 'includi'. Permette il comportamento 'mixin'. Viene utilizzato per ASCIUGARE il codice per evitare la duplicazione, ad esempio, se vi fossero più classi che avrebbero bisogno dello stesso codice all'interno del modulo.

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

Richiedere

Il metodo Require consente di caricare una libreria e ne impedisce il caricamento più di una volta. Il metodo request restituirà 'false' se si tenta di caricare la stessa libreria dopo la prima volta. Il metodo Requisito deve essere utilizzato solo se la libreria che si sta caricando è definita in un file separato, che di solito è il caso.

Quindi tiene traccia del fatto che quella libreria sia già stata caricata o meno. Inoltre, non è necessario specificare l'estensione ".rb" del nome del file della libreria. Ecco un esempio di come utilizzare richiedono. Posiziona il metodo request nella parte superiore del file ".rb":

Caricare

Il metodo di caricamento è quasi come il metodo di richiesta, tranne che non tiene traccia del caricamento o meno della libreria. Quindi è possibile caricare una libreria più volte e anche quando si utilizza il metodo load è necessario specificare l'estensione ".rb" del nome del file della libreria.

Estendere

Quando si utilizza il metodo di estensione invece di includere, si stanno aggiungendo i metodi del modulo come metodi di classe anziché come metodi di istanza.

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

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type

2

'Carica': inserisce il contenuto di un file (file di analisi ogni volta che viene chiamato il file)

'Require': inserisce un contenuto analizzato del file (file analizzato una volta e archiviato in memoria)

'Includi': include il modulo nella classe e può usare metodi all'interno del modulo come metodo di istanza della classe

'Estendi': include il modulo nella classe e può usare metodi all'interno del modulo come metodo di classe

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.