Ruby-Klasseninstanzvariablen und Vererbung
Habe ich eine Ruby-Klasse mit dem Namen LibraryItem
. Ich will assoziieren mit jeder Instanz dieser Klasse ein array von Parametern. Dieses array ist lang und sieht so ähnlich aus wie
['title', 'authors', 'location', ...]
Beachten Sie, dass diese Attribute sind nicht wirklich soll, werden Methoden, einfach nur eine Liste von Attributen, die eine LibraryItem
hat.
Als Nächstes möchte ich eine Unterklasse von LibraryItem
genannt LibraryBook
, hat eine Reihe von Attributen, die alle Attribute von LibraryItem
aber auch viele, viele mehr.
Irgendwann möchte ich mehrere Unterklassen von LibraryItem
jede mit Ihrer eigenen version der array @attributes
aber indem jede an LibraryItem
's @attributes
(z.B.LibraryBook
, LibraryDVD
, LibraryMap
usw.).
So, hier ist mein Versuch:
class LibraryItem < Object
class << self; attr_accessor :attributes; end
@attributes = ['title', 'authors', 'location',]
end
class LibraryBook < LibraryItem
@attributes.push('ISBN', 'pages')
end
Funktioniert das nicht. Ich bekomme die Fehlermeldung
undefined method `push' for nil:NilClass
Wenn es Arbeit wäre, würde ich wollen, so etwas wie dieses
puts LibraryItem.attributes
puts LibraryBook.attributes
Ausgabe
['title', 'authors', 'location']
['title', 'authors', 'location', 'ISBN', 'pages']
(Hinzugefügt Am 02-May-2010)
Eine Lösung ist, um @attributes
eine einfache Instanz-variable und fügen Sie die neuen Attribute für LibraryBoot
im initialize
- Methode (dies wurde vorgeschlagen von demas in einer der Antworten).
Während dies würde sicherlich funktionieren (und ist, in der Tat, was habe ich bisher gemacht), ich bin nicht glücklich mit diesem, wie es sub-optimal ist: warum sollte diese unveränderlichen arrays konstruiert werden jedes mal, wenn ein Objekt erstellt wird?
Was ich wirklich will, ist eine Klasse von Variablen, die Erben können von einer übergeordneten Klasse, aber wenn geändert, in der Kind-Klasse nicht ändern, die der übergeordneten Klasse.
InformationsquelleAutor der Frage rlandster | 2010-05-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da Sie erwähnen, dass die Attribute "fest" und "unveränderlich", ich gehe davon aus, dass du meinst, Sie wird sich nie ändern Ihren Wert, wenn das Objekt erstellt wird. In diesem Fall, etwas, das wie folgt funktionieren sollte:
Sind Sie manuell implementieren eine reader-Methode (statt
attr_accessor
erstellen es für Sie), die Verkleidungen der interne name des Arrays. In der Unterklasse, rufen Sie einfach die Vorgänger-Klasse " reader-Funktion, tack auf die zusätzlichen Felder im Zusammenhang mit der Kind-Klasse, und, dass die Rückkehr an den Aufrufer. Für den Benutzer, dieser erscheint wie ein read-only-member-variable namensattributes
hat, dass zusätzliche Werte in der sub-Klasse.InformationsquelleAutor der Antwort bta
Andere Lösung wäre, verwenden Sie die geerbt Haken:
InformationsquelleAutor der Antwort tomazy
Nur als version:
InformationsquelleAutor der Antwort demas
Aus Neugier, wird so etwas wie dieses arbeiten?
Dieses würde scheinen, zu produzieren das gewünschte Ergebnis - die ATTRIBUTE-array wird erweitert, wenn das class-Objekt wird erstellt, und die Werte der ATTRIBUTE variiert wie erwartet:
InformationsquelleAutor der Antwort Grant Goodale
ActiveSupport hat class_attribute Methode in rails Rand.
InformationsquelleAutor der Antwort Nick Vanderbilt
Erweitern @Nick Vanderbilt Antwort, mit active_support Sie dies tun, und das ist genau der kurzer hand möchte ich für diese Funktionalität. Hier ist ein vollständiges Beispiel:
Schande, es ist so schwer für ruby um dies zu erreichen, ohne dass eine Bibliothek dafür. Es ist das einzige, was ich vermisse von python. Und in meinem Fall, ich habe nichts dagegen, die Abhängigkeit von der active_support gem.
InformationsquelleAutor der Antwort Matt Connolly
In LibraryBook variable @Attribute ist eine neue unabhängige variable, Instanzvariable des Objekts LibraryBook, so dass es nicht initialisiert wurde und Sie die Fehlermeldung "undefined method ... für null"
Sie sollten die Initialisierung von LibraryItem attribut-Liste vor der Verwendung
InformationsquelleAutor der Antwort andrykonchin
Dies ist für strings (nichts wirklich), sondern als Felder, aber...
InformationsquelleAutor der Antwort Wayne Walker
Kann man es mit CINSTANTS auch. Keine überprüfung obwohl.
InformationsquelleAutor der Antwort Salil