Zmienne instancji zaczynają się od znaku at (@) i można się do nich odwoływać tylko w ramach metod klasowych. Różnią się od zmiennych lokalnych tym, że nie istnieją w żadnym konkretnym zakres. Zamiast tego podobna tabela zmiennych jest przechowywana dla każdej instancji klasy. Zmienne instancji znajdują się w instancji klasy, tak długo, jak instancja pozostaje przy życiu, zmienne instancji również będą istnieć.
Do zmiennych instancji można się odwoływać w dowolnej metodzie tej klasy. Wszystkie metody klasy używają tej samej instancji zmienna tabela, w przeciwieństwie do zmiennych lokalnych, w których każda metoda będzie miała inną tabelę zmiennych. Można jednak uzyskać dostęp do zmiennych instancji bez ich uprzedniego zdefiniowania. Nie spowoduje to wyjątku, ale wartość zmiennej będzie wynosić zero a jeśli uruchomisz Ruby z., pojawi się ostrzeżenie -w przełącznik.
Ten przykład demonstruje użycie zmiennych instancji. Zauważ, że szulernia zawiera -w przełącznik, który wyświetli ostrzeżenia, jeśli wystąpią. Zwróć także uwagę na nieprawidłowe użycie poza metodą w zakresie klasy. Jest to niepoprawne i omówione poniżej.
Dlaczego jest @test zmienna niepoprawna? Ma to związek z zakresem i tym, jak Ruby implementuje różne rzeczy. W ramach metody zakres zmiennej instancji odnosi się do konkretnego wystąpienia tej klasy. Jednak w zakresie klasy (wewnątrz klasy, ale poza żadnymi metodami), zasięg jest instancja klasy zakres. Ruby implementuje hierarchię klas poprzez tworzenie instancji Klasa obiekty, więc istnieje druga instancja podczas zabawy tutaj. Pierwszy instancja jest przykładem Klasa klasa i to gdzie @test ruszymy. Druga instancja to instancja TestClassi to gdzie @wartość ruszymy. To staje się trochę mylące, ale pamiętaj, aby nigdy nie używać @instance_variables poza metodami. Jeśli potrzebujesz pamięci dla całej klasy, użyj @@ zmienne_klasowe, które mogą być używane w dowolnym miejscu w zakresie klasy (wewnątrz lub na zewnątrz metod) i będą zachowywać się tak samo.
Zwykle nie można uzyskać dostępu do zmiennych instancji spoza obiektu. Na przykład w powyższym przykładzie nie można po prostu zadzwonić t. wartość lub wartość t. @ aby uzyskać dostęp do zmiennej instancji @wartość. To złamałoby zasady kapsułkowanie. Dotyczy to również instancji klas podrzędnych, nie mogą one uzyskać dostępu do zmiennych instancji należących do klasy nadrzędnej, mimo że technicznie są tego samego typu. Aby więc zapewnić dostęp do zmiennych instancji, akcesor metody muszą być zadeklarowane.
Poniższy przykład pokazuje, w jaki sposób można napisać metody akcesora. Pamiętaj jednak, że Rubin zapewnia skrót i że ten przykład istnieje tylko po to, aby pokazać, jak działają metody akcesora. Zasadniczo nieczęsto widuje się metody akcesora napisane w ten sposób, chyba że potrzebny jest jakaś dodatkowa logika dla akcesora.
Skróty sprawiają, że jest to trochę łatwiejsze i bardziej kompaktowe. Istnieją trzy z tych metod pomocniczych. Muszą być uruchamiane w zakresie klasy (wewnątrz klasy, ale poza wszelkimi metodami) i dynamicznie definiują metody podobne do metod zdefiniowanych w powyższym przykładzie. Nie ma tu żadnej magii i wyglądają jak słowa kluczowe w języku, ale tak naprawdę są to tylko dynamicznie definiujące metody. Ponadto te akcesoria zwykle znajdują się na szczycie klasy. To daje czytelnikowi natychmiastowy przegląd, które zmienne składowe będą dostępne poza klasą lub dla klas potomnych.
Istnieją trzy z tych metod dostępu. Każdy z nich pobiera listę symboli opisujących zmienne instancji, do których można uzyskać dostęp.
- attr_reader - Zdefiniuj metody „czytnika”, takie jak Nazwa metoda w powyższym przykładzie.
- attr_writer - Zdefiniuj metody „pisarza”, takie jak wiek = metoda w powyższym przykładzie.
- attr_accessor - Zdefiniuj metody „czytnika” i „pisarza”.
Kiedy używać zmiennych instancji
Kiedy już wiesz, jakie są zmienne instancji, kiedy ich używasz? Zmienne instancji powinny być używane, gdy reprezentują stan obiektu. Nazwisko i wiek studenta, jego stopnie itp. Nie należy ich używać do tymczasowego przechowywania, po to są zmienne lokalne. Można je jednak wykorzystać do tymczasowego przechowywania między wywołaniami metod do obliczeń wieloetapowych. Jeśli jednak to robisz, możesz ponownie przemyśleć skład metody i zamiast tego przekształcić te zmienne w parametry metody.