Nehmen wir an, ich habe eine Klasse mit ein paar "statischen" Variablen. Ich möchte eine Unterklasse dieser Klasse in der Lage sein, diese Variablen zu überschreiben, ohne die ursprüngliche Klasse zu beeinflussen. Dies ist nicht möglich, Klassenvariablen verwenden, da diese erscheint zwischen Subklassen und Super geteilt werden:Wie überschreibe ich eine Variable in einer Ruby-Unterklasse, ohne die Oberklasse zu beeinflussen?
class Foo
@@test = "a"
def speak; puts @@test; end
end
class Bar < Foo
@@test = "b"
end
Bar.new.speak
# b
Foo.new.speak
# b
Es ist nicht möglich Konstanten entweder:
class Foo
TEST = "a"
def speak; puts TEST; end
end
class Bar < Foo
TEST = "b"
end
Bar.new.speak
# a
Foo.new.speak
# a
Methoden in der übergeordneten Klasse definiert Konstanten ignoriert in der Unterklasse.
Das offensichtliche Problem zu umgehen ist es, Methoden für die Variablen zu definieren, die „außer Kraft gesetzt“ sein muss:
class Foo
def test; "a"; end
end
Aber das fühlt sich an wie ein Hack. Ich denke, das sollte mit Klassenvariablen möglich sein und ich mache es wahrscheinlich nur falsch. Zum Beispiel, wenn ich eine Unterklasse Object
(das ist, was passiert, in der Standardeinstellung):
class Foo < Object
@@bar = 123
end
Object.class_variable_get(:@@bar)
# NameError: uninitialized class variable @@bar in Object
Warum auf Object
nicht @@bar
Satz ist wie es in meinem Bar < Foo
Beispiel oben war?
Zusammengefasst: Wie überschreibe ich eine Variable in einer Unterklasse, ohne die Oberklasse zu beeinflussen?
Bearbeitete den Text der Antwort, um mehr Sinn zu machen, hoffe, dass es Ihnen nichts ausmacht. Das scheint mir der richtige Weg zu sein, also akzeptiere ich die Antwort. – Hubro
@Codemonkey Ihre ursprüngliche Frage betraf Variablen, keine Konstanten. Obwohl Sie in Ruby Konstanten überschreiben können, erhalten Sie Warnungen, und das wird für jeden, der Ihren Code liest, verwirrend sein. Denis 'Antwort ist die richtige Art, Variablen pro Klasse zu implementieren. – Max
@Max: Wenn Sie die ganze Frage lesen, wird klar, dass alles, was ich bin, eine Möglichkeit ist, einen * Wert * zu überschreiben, der an eine Klasse in einer Unterklasse gebunden ist - es ist nicht wichtig, ob es Variablen oder Konstanten sind. Ich stimme zu, dass "Variable" eine schlechte Wortwahl gewesen sein könnte. Die Verwendung solcher Konstanten scheint mir einfacher und intuitiver zu sein als die Definition von Meta-Klasse-Attribut-Lesern. Ich habe keine Warnungen bekommen, Konstanten in Unterklassen mit dem gleichen Namen wie Konstanten in ihren Oberklassen zu definieren (wie im Beispiel dieser Antwort). – Hubro