Ich komme aus Java und arbeite jetzt mehr mit Ruby.
Eine Sprachfunktion, mit der ich nicht vertraut bin, ist die module
. Ich frage mich, was genau ein ist module
und wann Sie einen verwenden und warum Sie einen module
über einen verwenden class
.
Antworten:
Die erste Antwort ist gut und gibt einige strukturelle Antworten, aber ein anderer Ansatz besteht darin, darüber nachzudenken, was Sie tun. Bei Modulen geht es darum, Methoden bereitzustellen, die Sie für mehrere Klassen verwenden können. Stellen Sie sich diese als "Bibliotheken" vor (wie Sie es in einer Rails-App sehen würden). Klassen handeln von Objekten; Module sind über Funktionen.
Beispielsweise sind Authentifizierungs- und Autorisierungssysteme gute Beispiele für Module. Authentifizierungssysteme funktionieren über mehrere Klassen auf App-Ebene (Benutzer werden authentifiziert, Sitzungen verwalten die Authentifizierung, viele andere Klassen verhalten sich je nach Authentifizierungsstatus unterschiedlich), sodass Authentifizierungssysteme als gemeinsam genutzte APIs fungieren.
Sie können ein Modul auch verwenden, wenn Sie Methoden für mehrere Apps gemeinsam genutzt haben (auch hier ist das Bibliotheksmodell gut).
quelle
quelle
Ich bin überrascht, dass dies noch niemand gesagt hat.
Da der Fragesteller aus Java stammt (und ich auch), ist hier eine Analogie, die hilft.
Klassen sind einfach wie Java-Klassen.
Module sind wie statische Java-Klassen. Denken Sie an den
Math
Unterricht in Java. Sie instanziieren es nicht und verwenden die Methoden in der statischen Klasse (z. B.Math.random()
) wieder.quelle
extend self
) und ihre Methoden für dieself
Metaklasse ihres Benutzers verfügbar machen . Dies ermöglicht den Versand einer Methode wierandom()
auf einemMath
Modul. Die Methoden eines Moduls können jedoch naturgemäß nicht allein aufgerufen werdenself
. Dies hat mit Rubys Vorstellung vonself
, seinen Metaklassen und der Funktionsweise der Methodensuche zu tun . Weitere Informationen finden Sie unter "Metaprogramming Ruby" - Paolo Perlotta.Grundsätzlich kann das Modul nicht instanziiert werden. Wenn eine Klasse ein Modul enthält, wird eine Proxy-Superklasse generiert, die Zugriff auf alle Modulmethoden sowie die Klassenmethoden bietet.
Ein Modul kann von mehreren Klassen eingeschlossen werden. Module können nicht vererbt werden, aber dieses "Mixin" -Modell bietet eine nützliche Art der "Mehrfachvererbung". OO-Puristen werden dieser Aussage nicht zustimmen, aber lassen Sie nicht zu, dass Reinheit die Arbeit behindert.
(Diese Antwort war ursprünglich verlinkt
http://www.rubycentral.com/pickaxe/classes.html
, aber dieser Link und seine Domain sind nicht mehr aktiv.)quelle
extend
eine Klasse "statische" Methoden annehmen können . Ruby unterscheidet eigentlich überhaupt nicht zwischen "Instanz" - und "Klasse / Statik" -Methoden, sondern nur zwischen deren Empfängern.Module
in Ruby entspricht bis zu einem gewissen Grad der abstrakten Java- Klasse - hat Instanzmethoden, Klassen können davon erben (viainclude
, Ruby-Leute nennen es ein "Mixin"), hat aber keine Instanzen. Es gibt noch andere kleine Unterschiede, aber so viele Informationen reichen aus, um Ihnen den Einstieg zu erleichtern.quelle
Namespace: Module sind Namespaces ... die in Java nicht existieren;)
Ich habe auch von Java und Python zu Ruby gewechselt, ich erinnere mich, dass ich genau die gleiche Frage hatte ...
Die einfachste Antwort ist also, dass das Modul ein Namespace ist, der in Java nicht existiert. In Java ist die dem Namespace am nächsten liegende Denkweise ein Paket .
Ein Modul in Ruby ist also wie in Java:
Klasse? Keine
Schnittstelle? Keine
abstrakte Klasse? Kein
Paket? Ja vielleicht)
statische Methoden in Klassen in Java: wie Methoden in Modulen in Ruby
In Java ist die Mindesteinheit eine Klasse. Sie können keine Funktion außerhalb einer Klasse haben. Bei Ruby ist dies jedoch möglich (wie bei Python).
Was steckt also in einem Modul?
Klassen, Methoden, Konstanten. Das Modul schützt sie unter diesem Namespace.
Keine Instanz: Module können nicht zum Erstellen von Instanzen verwendet werden
Gemischte Ins: Manchmal sind Vererbungsmodelle nicht gut für Klassen, aber in Bezug auf die Funktionalität möchten Sie eine Reihe von Klassen / Methoden / Konstanten zusammenfassen
Regeln für Module in Ruby:
- Modulnamen sind UpperCamelCase
- Konstanten innerhalb von Modulen sind ALL CAPS (diese Regel ist für alle Ruby-Konstanten gleich, nicht modulspezifisch )
- Zugriffsmethoden: use. Operator
- Zugriffskonstanten: use :: symbol
einfaches Beispiel eines Moduls:
Verwendung von Methoden innerhalb eines Moduls:
Verwendung von Konstanten eines Moduls:
Einige andere Konventionen zu Modulen:
Verwenden Sie ein Modul in einer Datei (z. B. Ruby-Klassen, eine Klasse pro Ruby-Datei).
quelle
Fazit: Ein Modul ist eine Kreuzung zwischen einer statischen / Utility-Klasse und einem Mixin.
Mixins sind wiederverwendbare Teile einer "teilweisen" Implementierung, die in Mix & Match-Weise kombiniert (oder komponiert) werden können, um das Schreiben neuer Klassen zu erleichtern. Diese Klassen können natürlich zusätzlich einen eigenen Status und / oder Code haben.
quelle
Klasse
Wenn Sie eine Klasse definieren, definieren Sie einen Entwurf für einen Datentyp. Klasse hält Daten, verfügt über Methoden, die mit diesen Daten interagieren und zum Instanziieren von Objekten verwendet werden.
Modul
Module sind eine Möglichkeit, Methoden, Klassen und Konstanten zu gruppieren.
Module bieten Ihnen zwei Hauptvorteile:
=> Module bieten einen Namespace und verhindern Namenskonflikte. Mithilfe des Namespace können Konflikte mit Funktionen und Klassen mit demselben Namen vermieden werden, die von einer anderen Person geschrieben wurden.
=> Module implementieren die Mixin-Funktion.
quelle
Zunächst einige Ähnlichkeiten, die noch nicht erwähnt wurden. Ruby unterstützt offene Klassen, aber auch offene Module. Schließlich erbt Class von Module in der Class-Vererbungskette, sodass Class und Module ein ähnliches Verhalten aufweisen.
Aber Sie müssen sich fragen, was der Zweck ist, sowohl eine Klasse als auch ein Modul in einer Programmiersprache zu haben? Eine Klasse soll eine Blaupause zum Erstellen von Instanzen sein, und jede Instanz ist eine realisierte Variation der Blaupause. Eine Instanz ist nur eine realisierte Variation einer Blaupause (der Klasse). Klassen fungieren dann natürlich als Objekterstellung. Da wir manchmal möchten, dass eine Blaupause von einer anderen Blaupause abgeleitet wird, sind Klassen so konzipiert, dass sie die Vererbung unterstützen.
Module können nicht instanziiert werden, erstellen keine Objekte und unterstützen keine Vererbung. Denken Sie also daran, dass ein Modul NICHT von einem anderen erbt!
Was bringt es dann, Module in einer Sprache zu haben? Eine offensichtliche Verwendung von Modulen besteht darin, einen Namespace zu erstellen, und Sie werden dies auch bei anderen Sprachen bemerken. Wiederum ist das Coole an Ruby, dass Module wieder geöffnet werden können (genau wie Klassen). Dies ist eine große Verwendung, wenn Sie einen Namespace in verschiedenen Ruby-Dateien wiederverwenden möchten:
Es gibt jedoch keine Vererbung zwischen Modulen:
Das Apple-Modul hat keine Methoden vom Green-Modul geerbt. Wenn wir Apple in die Fruit-Klasse aufgenommen haben, werden die Methoden des Apple-Moduls zur Ahnenkette der Apple-Instanzen hinzugefügt, nicht jedoch die Methoden des Green-Moduls, obwohl das Green-Modul Modul wurde im Apple-Modul definiert.
Wie erhalten wir Zugang zur grünen Methode? Sie müssen es explizit in Ihre Klasse aufnehmen:
Aber Ruby hat eine andere wichtige Verwendung für Module. Dies ist die Mixin-Funktion, die ich in einer anderen Antwort auf SO beschreibe. Zusammenfassend lässt sich sagen, dass Sie mit Mixins Methoden in die Vererbungskette von Objekten definieren können. Über Mixins können Sie Methoden zur Vererbungskette von Objektinstanzen (include) oder zur singleton_class von self (extens) hinzufügen.
quelle