Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
W Ruby istnieje kilka typów zmiennych, które różnią się tym, do kogo należą - do obiektu, klasy czy wszystkich potomków jednocześnie. Rozważmy to prosto i na przykładach.
@ - zmienna instancji (instance variable)
To zwykła zmienna, która należy do konkretnego obiektu. Każda instancja klasy (obiekt) ma swoją własną kopię takiej zmiennej.
class User
def initialize(name)
@name = name
end
def name
@name
end
end
u1 = User.new("Oleh")
u2 = User.new("Ira")
u1.name # => "Oleh"
u2.name # => "Ira"
Każdy użytkownik ma swoje imię. @name nie dzieli się między obiektami - to ich dane osobowe.
@@ - zmienna klasy (class variable)
Zmienna z dwoma znakami @ (@@) jest wspólna dla wszystkich instancji i podklas. Żyje w całej hierarchii klas.
class Animal
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
end
class Dog < Animal; end
a1 = Animal.new
d1 = Dog.new
Animal.count # => 2
Dog.count # => 2
Zarówno Animal, jak i Dog widzą tę samą zmienną @@count. Jeśli podklasa ją zmienia - wpływa to na klasę nadrzędną. Z tego powodu @@ uważane są za niebezpieczną i przestarzałą praktykę - lepiej unikać ich użycia.
Zmienna instancji klasy - bezpieczna alternatywa dla @@
Można stworzyć zmienną na poziomie klasy, ale tak, aby należała tylko do tej klasy, a nie do jej dziedziców. To zwykła zmienna @, ale zadeklarowana na poziomie samej klasy (a nie wewnątrz initialize).
class User
@count = 0
def self.add_user
@count += 1
end
def self.count
@count
end
end
class Admin < User; end
User.add_user
User.count # => 1
Admin.count # => nil
W tym przykładzie User ma swoją własną @count, a Admin - oddzielną (początkowo nil, dopóki nie zostanie zdefiniowana). To sprawia, że kod jest bezpieczny i przewidywalny.
Ten post nie ma jeszcze żadnych dodatków od autora.