Ruby/Zmienne instancji

Zmienne instancji

edytuj

Zmienna instancji ma nazwę zaczynającą się znakiem @, a jej zasięg ograniczony jest tylko do obiektu wskazywanego przez self. Dwa różne obiekty, nawet jeśli należą do tej samej klasy, mogą mieć różne wartości swoich zmiennych instancji. Na zewnątrz obiektu zmienne instancji nie mogą być zmienione, ani nawet odczytane (zmienne instancji w Rubim nigdy nie są publiczne), chyba że za pośrednictwem metod wyraźnie dostarczonych przez programistę. Tak jak zmienne globalne, zmienne instancji mają wartość nil dopóki nie zostaną zainicjalizowane.

Zmienne instancji nie muszą być zadeklarowane. Wskazuje to na elastyczną strukturę obiektu. W rzeczywistości, każda zmienna instancji jest dynamicznie dołączana do obiektu w czasie pierwszego przypisania jej wartości.

irb(main):001:0> class TestInst
irb(main):002:1> def ustaw_a(n)
irb(main):003:2> @a = n
irb(main):004:2> end
irb(main):005:1> def ustaw_b(n)
irb(main):006:2> @b = n
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> i = TestInst.new
=> #<TestInst:0x2e46770>
irb(main):010:0> i.ustaw_a(2)
=> 2
irb(main):011:0> i
=> #<TestInst:0x2e46770 @a=2>
irb(main):012:0> i.ustaw_b(4)
=> 4
irb(main):013:0> i
=> #<TestInst:0x2e46770 @b=4, @a=2>

Zauważ, że powyższe i nie zwraca wartości @b dopóki nie zostanie wywołana metoda ustaw_b.

Wiedzę o zmiennych instancji możemy wykorzystać do udoskonalenia naszej klasy Zwierze z rozdziału o zmiennych klasowych:

class Zwierze
  @@ilosc = 0
  
  def initialize(nazwa, wiek)
    @nazwa = nazwa
    @wiek = wiek
    @@ilosc += 1
  end
  
  def self.populacja
    puts "Populacja zwierzat liczy sztuk: #{@@ilosc}"
  end
  
  def podaj_nazwe
    @nazwa
  end
  
  def podaj_wiek
    @wiek
  end
  
  def to_s
     "Jestem #{@wiek}-letni #{@nazwa}"
  end
end

pies = Zwierze.new("pies", 3)
kot = Zwierze.new("kot", 5)

puts pies         #=> Jestem 3-letni pies
puts kot          #=> Jestem 5-letni kot
Zwierze.populacja #=> Populacja zwierzat liczy sztuk: 2