Załóżmy, że mam klasę z kilkoma zmiennymi "statycznymi". Chcę podklas tej klasy, aby móc zastąpić te zmienne bez wpływu na oryginalną klasę. Nie jest to możliwe przy użyciu zmiennych klasowych, gdyż te wydają się być dzielone między podklasy i superklas:Jak przesłonić zmienną w podklasie Ruby bez wpływu na nadklasę?
class Foo
@@test = "a"
def speak; puts @@test; end
end
class Bar < Foo
@@test = "b"
end
Bar.new.speak
# b
Foo.new.speak
# b
To nie jest możliwe przy użyciu stałych albo:
class Foo
TEST = "a"
def speak; puts TEST; end
end
class Bar < Foo
TEST = "b"
end
Bar.new.speak
# a
Foo.new.speak
# a
Metody zdefiniowane w nadrzędnej ignoruje stałych w podklasie.
Oczywistym rozwiązaniem jest zdefiniowanie metod dla zmiennych, które muszą być „przeciążać”:
class Foo
def test; "a"; end
end
jednak, że czuje się jak hack. Czuję, że powinno to być możliwe przy użyciu zmiennych klasowych i prawdopodobnie robię to źle. Na przykład, kiedy podklasy Object
(czyli to, co dzieje się domyślnie):
class Foo < Object
@@bar = 123
end
Object.class_variable_get(:@@bar)
# NameError: uninitialized class variable @@bar in Object
Dlaczego nie jest @@bar
zestaw na Object
jak to było w moim Bar < Foo
powyższym przykładzie?
Podsumowując: w jaki sposób przesłonić zmienną w podklasie bez wpływu na nadklasę?
Edytował tekst odpowiedzi, aby zachować więcej sensu, mam nadzieję, że nie masz nic przeciwko. Wydaje mi się, że jest to najbardziej poprawna metoda, więc akceptuję odpowiedź. – Hubro
@Codemonkey Pierwotne pytanie dotyczyło zmiennych, a nie stałych. Chociaż Ruby pozwala nadpisywać stałe, otrzymasz ostrzeżenia o tym i będzie to mylące dla każdego czytającego twój kod. Odpowiedź Denisa jest właściwym sposobem implementacji zmiennych na klasy. – Max
@Max: Jeśli przeczytasz całe pytanie, będzie jasne, że wszystko, co robię, jest sposobem na przesłonięcie wartości * związanej z klasą w podklasie - nie ma znaczenia, czy są to zmienne czy stałe. Zgadzam się, że "zmienna" mogła być złym wyborem słów. Używanie takich stałych wydaje mi się prostsze i bardziej intuicyjne niż definiowanie czytników atrybutów meta-klasy. Nie otrzymałem żadnych ostrzeżeń od definiowania stałych w podklasach o tej samej nazwie, co stałe w ich nadklasach (jak w tym przykładzie odpowiedzi). – Hubro