Ruby bietet diese praktische und bequeme Möglichkeit, Instanzvariablen mithilfe von Schlüsseln wie freizugeben
attr_accessor :var
attr_reader :var
attr_writer :var
Warum sollte ich wählen attr_reader
oder attr_writer
wenn ich einfach verwenden könnte attr_accessor
? Gibt es so etwas wie Leistung (was ich bezweifle)? Ich denke, es gibt einen Grund, sonst hätten sie solche Schlüssel nicht gemacht.
Antworten:
Sie können die verschiedenen Zugriffsmethoden verwenden, um jemandem, der Ihren Code liest, Ihre Absicht mitzuteilen und das Schreiben von Klassen zu vereinfachen, die unabhängig vom Aufruf ihrer öffentlichen API ordnungsgemäß funktionieren.
Hier kann ich sehen, dass ich das Alter sowohl lesen als auch schreiben kann.
Hier kann ich sehen, dass ich nur das Alter lesen darf. Stellen Sie sich vor, dass es vom Konstruktor dieser Klasse festgelegt wird und danach konstant bleibt. Wenn es einen Mutator (Writer) für das Alter gibt und die Klasse unter der Annahme geschrieben wird, dass sich das einmal festgelegte Alter nicht ändert, kann ein Fehler durch den Code entstehen, der diesen Mutator aufruft.
Aber was passiert hinter den Kulissen?
Wenn Sie schreiben:
Das wird übersetzt in:
Wenn Sie schreiben:
Das wird übersetzt in:
Wenn Sie schreiben:
Das wird übersetzt in:
Wenn Sie das wissen, können Sie darüber nachdenken: Wenn Sie nicht die attr _...-Helfer hätten und die Accessoren selbst schreiben müssten, würden Sie dann mehr Accessoren schreiben, als Ihre Klasse benötigt? Wenn beispielsweise das Alter nur gelesen werden müsste, würden Sie dann auch eine Methode schreiben, mit der es geschrieben werden kann?
quelle
attr_reader :a
gegenüberdef a; return a; end
confreaks.net/videos/…attr_reader
definierte Accessor 86% der Zeit, die der manuell definierte Accessor benötigt. Für Ruby 1.9.0 benötigt derattr_reader
definierte Accessor 94% der Zeit, die der manuell definierte Accessor benötigt. In allen meinen Tests sind Accessoren jedoch schnell: Ein Accessor benötigt ungefähr 820 Nanosekunden (Ruby 1.8.7) oder 440 Nanosekunden (Ruby 1.9). Bei diesen Geschwindigkeiten müssen Sie einen Accessor hunderte Millionen Mal anrufen, um die Leistungattr_accessor
zu verbessern und die Gesamtlaufzeit um nur eine Sekunde zu verbessern.attr_accessor :a, :b
Alle obigen Antworten sind richtig;
attr_reader
undattr_writer
sind bequemer zu schreiben, als die Methoden, für die sie Abkürzungen sind, manuell einzugeben. Abgesehen davon bieten sie eine viel bessere Leistung als das Schreiben der Methodendefinition selbst. Weitere Informationen finden Sie auf Folie 152 ab diesem Vortrag ( PDF ) von Aaron Patterson.quelle
Nicht alle Attribute eines Objekts sollen direkt von außerhalb der Klasse festgelegt werden. Autoren für alle Ihre Instanzvariablen zu haben, ist im Allgemeinen ein Zeichen für eine schwache Kapselung und eine Warnung, dass Sie zu viel Kopplung zwischen Ihren Klassen einführen.
Als praktisches Beispiel: Ich habe ein Designprogramm geschrieben, in dem Sie Gegenstände in Behälter legen. Der Artikel hatte
attr_reader :container
, aber es war nicht sinnvoll, einen Schreiber anzubieten, da sich der Container des Artikels nur ändern sollte, wenn er in einen neuen platziert wird, für den auch Positionsinformationen erforderlich sind.quelle
Es ist wichtig zu verstehen, dass Accessoren den Zugriff auf Variablen einschränken, nicht jedoch auf deren Inhalt. In Ruby ist wie in einigen anderen OO-Sprachen jede Variable ein Zeiger auf eine Instanz. Wenn Sie beispielsweise ein Attribut für einen Hash haben und es auf "schreibgeschützt" setzen, können Sie dessen Inhalt immer ändern, nicht jedoch den Inhalt des Zeigers. Schau dir das an:
Wie Sie sehen, ist es möglich, ein Schlüssel / Wert-Paar aus dem Hash @a zu löschen, indem Sie neue Schlüssel hinzufügen, Werte ändern usw. Sie können jedoch nicht auf ein neues Objekt verweisen, da es sich um eine schreibgeschützte Instanzvariable handelt.
quelle
Sie möchten nicht immer, dass Ihre Instanzvariablen von außerhalb der Klasse vollständig zugänglich sind. Es gibt viele Fälle, in denen das Ermöglichen des Lesezugriffs auf eine Instanzvariable sinnvoll ist, das Schreiben jedoch möglicherweise nicht (z. B. ein Modell, das Daten aus einer schreibgeschützten Quelle abruft). Es gibt Fälle, in denen Sie das Gegenteil wollen, aber ich kann mir keine vorstellen, die mir nicht auf den Kopf gestellt wurden.
quelle