Was ist der Unterschied zwischen Include und Require in Ruby?

465

Meine Frage ähnelt " Was ist der Unterschied zwischen Einschließen und Erweitern in Ruby? ".

Was ist der Unterschied zwischen requireund includein Ruby? Wenn ich nur die Methoden eines Moduls in meiner Klasse verwenden möchte, sollte ich requirees oder includees?

Owen
quelle
1
Für das, was es wert ist, finden Sie hier Links zur Community-Dokumentation für requireund include, und auch relevant , Module#append_features.

Antworten:

543

Was ist der Unterschied zwischen "include" und "require" in Ruby?

Antworten:

Die Include- und Require-Methoden machen sehr unterschiedliche Dinge.

Die Methode require macht das, was include in den meisten anderen Programmiersprachen macht: Führen Sie eine andere Datei aus. Es verfolgt auch, was Sie in der Vergangenheit benötigt haben, und benötigt nicht zweimal dieselbe Datei. Um eine andere Datei ohne diese zusätzliche Funktionalität auszuführen, können Sie die Lademethode verwenden.

Die include-Methode übernimmt alle Methoden aus einem anderen Modul und schließt sie in das aktuelle Modul ein. Dies ist eine Sache auf Sprachebene im Gegensatz zu einer Sache auf Dateiebene wie bei require. Die include-Methode ist der primäre Weg, um Klassen mit anderen Modulen zu erweitern (normalerweise als Mix-Ins bezeichnet). Wenn Ihre Klasse beispielsweise die Methode "each" definiert, können Sie das Mixin-Modul Enumerable einschließen und es kann als Sammlung fungieren. Dies kann verwirrend sein, da das Include-Verb in anderen Sprachen sehr unterschiedlich verwendet wird.

Quelle

Wenn Sie also nur ein Modul verwenden möchten, anstatt es zu erweitern oder ein Mix-In durchzuführen, sollten Sie es verwenden require.

Seltsamerweise ist Ruby's requireanalog zu C's include, während Ruby's includefast nichts mit C's zu tun hat include.

HanClinto
quelle
45
Tatsächlich lädt Cs include eine Datei nicht wie erforderlich, sondern ersetzt stattdessen die Zeile #include durch den Inhalt der Datei. Eingeschlossene Dateien müssen nicht "Header" sein und #include muss nicht am Anfang der Datei stehen, sondern kann sich überall befinden, beispielsweise in der Klasse oder sogar in einer Methodendefinition. Dies bedeutet, dass Sie in C ++ mischen können, indem Sie einige Methoden in eine Datei schreiben und in den Code einer Klasse aufnehmen, genau wie Sie es in Ruby tun würden. Sie sind also nicht so weit, obwohl es in Cs tatsächlich keine übliche Praxis ist.
mb14
13
Diese Antwort könnte durch die Aufnahme von Beispielen profitieren.
Travis Bear
12
Der Kommentar von mb14 impliziert dies, muss jedoch explizit angegeben werden: Entgegen der Antwort "führt" require eine Datei nicht "aus", sondern lädt sie so, als ob sie Teil der enthaltenen Datei wäre. Dies mag wie semantisches Nitpicking erscheinen, aber eigentlich ist es ein ziemlich wichtiger Unterschied.
Lonny Eachus
Tolle Erklärung. Vielen Dank, dass Sie den Punkt mit der letzten Aussage nach Hause gebracht haben: "Seltsamerweise ist Rubys Anforderung analog zu Cs Include, während Rubys Include fast nichts mit Cs Include zu tun hat."
ArtSabintsev
1
@ GregSchmit: includeIn Ruby ist einfach Vererbung. class C; include M endmacht Mdie Oberklasse von Cund die (frühere) Oberklasse Cder Oberklasse von M. Ich denke nicht, dass Cs includedurch Vererbung funktioniert, ich denke, es ist eine einfache textuelle / lexikalische Substitution.
Jörg W Mittag
100

Wenn Sie ein Modul verwenden, bedeutet dies, dass Sie alle Methoden in Ihre Klasse bringen. Wenn Sie extendeine Klasse mit einem Modul haben, bedeutet dies, dass Sie die Methoden des Moduls als Klasse "einbringen" . Wenn Sie includeeine Klasse mit einem Modul haben, bedeutet dies, dass Sie die Methoden des Moduls als Instanzmethoden "einbringen" .

EX:

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

 class B
   include A
 end

 class C
   extend A
 end

B.say => undefinierte Methode 'say' für B: Class

B.new.say => das ist Modul A.

C.say => das ist Modul A.

C.new.say => undefinierte Methode 'say' für C: Class

Peter Dang
quelle
23
Ich denke, dies beantwortet die Frage nicht, aber es ist das, wonach ich gesucht habe =)
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
2
Dies beantwortet nicht wirklich die Frage, was die Unterschiede zwischen requireund sindinclude sind.
94

Aus dem Metaprogramming Ruby-Buch,

Das require() Methode ist ziemlich ähnlich load(), aber für einen anderen Zweck gedacht. Sie verwenden load()zum Ausführen von Code und require()zum Importieren von Bibliotheken.

Pratik Khadloya
quelle
73
Upvote für nicht mit einer anderen Sprache in Ihrer Antwort zu vergleichen :)
Stevo
Stimmen Sie ab, wenn Sie im Zusammenhang mit der Frage keine Antwort geben: "Wenn ich nur die Methoden eines Moduls in meiner Klasse verwenden möchte?"
Benc
57
  • Ruby requireist eher wie "include" in anderen Sprachen (wie C). Es teilt Ruby mit, dass Sie den Inhalt einer anderen Datei einbringen möchten . Ähnliche Mechanismen in anderen Sprachen sind:

  • Ruby includeist ein objektorientierter Vererbungsmechanismus, der für Mixins verwendet wird .

Es gibt eine gute Erklärung hier :

[Die] einfache Antwort ist, dass erfordern und einschließen im Wesentlichen nichts miteinander zu tun haben.

"require" ähnelt dem C include, was zu Verwirrung bei Neulingen führen kann. (Ein bemerkenswerter Unterschied besteht darin, dass Einheimische in der erforderlichen Datei "verdampfen", wenn die Anforderung erfüllt ist.)

Das Ruby- Include ist nichts anderes als das C-Include. Die include-Anweisung "mischt" ein Modul in eine Klasse ein. Es ist eine begrenzte Form der Mehrfachvererbung . Ein enthaltenes Modul verleiht der Sache, einschließlich, buchstäblich eine "Ist-Eine" -Beziehung.

Betonung hinzugefügt.

Bradheintz
quelle
7

Haben Sie jemals versucht, requireein Modul? Was waren die Ergebnisse? Probiere es einfach:

MyModule = Module.new
require MyModule # see what happens

Module können nicht benötigt werden, nur enthalten!

Boris Stitnicky
quelle
Die Behauptung hier ist nicht richtig. Module können erforderlich sein. Und jeder, der den obigen Code ausführt, wird feststellen, dass er das gleiche Ergebnis ( TypeError) erhält, wenn das Wort Modulein geändert wird Class.
pjd
7

Aus der Programmierung von Ruby 1.9

Wir werden ein paar Punkte zur include-Anweisung machen, bevor wir fortfahren. Erstens hat es nichts mit Dateien zu tun. C-Programmierer verwenden eine Präprozessor-Direktive namens #include, um den Inhalt einer Datei während der Kompilierung in eine andere einzufügen. Die Ruby include-Anweisung verweist einfach auf ein Modul. Wenn sich dieses Modul in einer separaten Datei befindet, müssen Sie require (oder den weniger häufig verwendeten Cousin load) verwenden, um diese Datei zu ziehen, bevor Sie include verwenden. Zweitens kopiert ein Ruby-Include nicht einfach die Instanzmethoden des Moduls in die Klasse. Stattdessen wird von der Klasse auf das enthaltene Modul verwiesen. Wenn mehrere Klassen dieses Modul enthalten, zeigen alle auf dasselbe. Wenn Sie die Definition einer Methode innerhalb eines Moduls ändern, auch während Ihr Programm ausgeführt wird,

Cizixs
quelle
3

Einschließen Wenn Sie ein Modul wie unten gezeigt in Ihre Klasse aufnehmen, ist es so, als hätten Sie den im Modul definierten Code genommen und in die Klasse eingefügt, wo Sie ihn 'einschließen'. Es erlaubt das 'Mixin'-Verhalten. Es wird verwendet, um Ihren Code auszutrocknen, um Doppelarbeit zu vermeiden, beispielsweise wenn es mehrere Klassen gibt, die denselben Code innerhalb des Moduls benötigen.

Laden Die Lademethode ähnelt fast der Require-Methode, verfolgt jedoch nicht, ob diese Bibliothek geladen wurde oder nicht. Es ist also möglich, eine Bibliothek mehrmals zu laden. Wenn Sie die Lademethode verwenden, müssen Sie die Erweiterung „.rb“ des Bibliotheksdateinamens angeben.

Erforderlich Mit der Methode require können Sie eine Bibliothek laden und verhindern, dass sie mehrmals geladen wird. Die require-Methode gibt 'false' zurück, wenn Sie versuchen, dieselbe Bibliothek nach dem ersten Mal zu laden. Die Methode require muss nur verwendet werden, wenn die von Ihnen geladene Bibliothek in einer separaten Datei definiert ist. Dies ist normalerweise der Fall.

Sie können dies bevorzugen http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/

Sanket
quelle
3

Im Folgenden sind einige grundlegende Unterschiede zwischen erforderlich und enthalten aufgeführt:

Benötigen:

  1. Require liest die Datei aus dem Dateisystem, analysiert sie, speichert sie im Speicher und führt sie an einem bestimmten Ort aus. Wenn Sie also während der Ausführung des Skripts überhaupt etwas ändern, wird diese Änderung nicht berücksichtigt.
  2. Wir benötigen eine Datei nach Namen, nicht nach Modulnamen.
  3. Es wird normalerweise für Bibliotheken und Erweiterungen verwendet.

Umfassen:

  1. Wenn Sie ein Modul in Ihre Klasse aufnehmen, verhält es sich so, als hätten Sie den in Ihrem Modul definierten Code in Ihre Klasse eingefügt.
  2. Wir geben den Modulnamen an, nicht den Dateinamen.
  3. Es wird normalerweise verwendet, um den Code auszutrocknen und Doppelspurigkeiten im Code zu entfernen.
Awais Shafqat
quelle
2
require(name)

Es wird bolean true / false zurückgeben

Der Name, der als Parameter an require, ruby ​​übergeben wird, versucht, die Quelldatei mit diesem Namen in Ihrem Ladepfad zu finden. Die require-Methode gibt 'false' zurück, wenn Sie versuchen, dieselbe Bibliothek nach dem ersten Mal zu laden. Die Methode require muss nur verwendet werden, wenn die zu ladende Bibliothek in einer separaten Datei definiert ist. So wird nachverfolgt, ob diese Bibliothek bereits geladen wurde oder nicht.

include module_name

Angenommen, Sie haben einige Methoden, die Sie in zwei verschiedenen Klassen haben müssen. Dann müssen Sie sie nicht in beiden Klassen schreiben. Stattdessen können Sie es im Modul definieren. Und dann dieses Modul in andere Klassen aufnehmen. Es wird von Ruby bereitgestellt, um das DRY-Prinzip sicherzustellen. Es wird verwendet, um Ihren Code auszutrocknen, um Doppelarbeit zu vermeiden

Shrinivas
quelle
2

Umfassen

Wenn Sie includeein Modul in Ihre Klasse aufnehmen, ist es so, als hätten Sie den im Modul definierten Code genommen und in die Klasse eingefügt, wo Sie ihn 'einschließen'. Es erlaubt das 'Mixin'-Verhalten. Es wird verwendet, um Ihren Code auszutrocknen, um Doppelarbeit zu vermeiden, beispielsweise wenn es mehrere Klassen gibt, die denselben Code innerhalb des Moduls benötigen.

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

Benötigen

Mit der Methode require können Sie eine Bibliothek laden und verhindern, dass sie mehrmals geladen wird. Die require-Methode gibt 'false' zurück, wenn Sie versuchen, dieselbe Bibliothek nach dem ersten Mal zu laden. Die Methode require muss nur verwendet werden, wenn die von Ihnen geladene Bibliothek in einer separaten Datei definiert ist. Dies ist normalerweise der Fall.

So wird nachverfolgt, ob diese Bibliothek bereits geladen wurde oder nicht. Sie müssen auch nicht die Erweiterung ".rb" des Bibliotheksdateinamens angeben. Hier ist ein Beispiel für die Verwendung von require. Platzieren Sie die Methode require ganz oben in Ihrer ".rb" -Datei:

Belastung

Die Lademethode ähnelt fast der Require-Methode, verfolgt jedoch nicht, ob diese Bibliothek geladen wurde oder nicht. Es ist also möglich, eine Bibliothek mehrmals zu laden. Wenn Sie die Lademethode verwenden, müssen Sie die Erweiterung „.rb“ des Bibliotheksdateinamens angeben.

Erweitern

Wenn Sie die Extend-Methode anstelle von Include verwenden, fügen Sie die Methoden des Moduls als Klassenmethoden statt als Instanzmethoden hinzu.

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
quelle
2

'Laden' - fügt den Inhalt einer Datei ein. (Analysiert die Datei jedes Mal, wenn die Datei aufgerufen wird.)

'Erforderlich' - fügt einen analysierten Dateiinhalt ein (Datei einmal analysiert und im Speicher gespeichert)

'Include' - schließt das Modul in die Klasse ein und kann Methoden innerhalb des Moduls als Instanzmethode der Klasse verwenden

'Erweitern' - schließt das Modul in die Klasse ein und kann Methoden innerhalb des Moduls als Klassenmethode verwenden

Vaishali Venkatesan
quelle