Как в Ruby при создании объекта класса сохранить в массив созданных объектов?
Например:
class People
attr_accessor :name, :age
def initialize (name, age)
@name = name
@age = age
@peoples = []
end
def add_new
end
def list
puts @peoples
end
end
Ответ
Зависит от того, как вы хотите поступить при наследовании.
Вот решение, использующее переменную экземпляра класса (class instance variable), которая у каждого класса собственная, а потому и списки у наследников получатся отдельными:
class A
def initialize
self.class.all << self
end
def self.all # self.___ метод определяется у класса, а не его объектов
@all ||= [] # вернуть имеющийся или записать туда пустой массив при первом обращении
end
end
Обратите внимание, что внутри этих методов self разный:
в self.all (A.all) это сам класс
в initialize (A#initialize) это создаваемый объект класса, поэтому чтобы добраться до класса используется self.class
Проверяем, как работает:
A.all # => []
A.new; A.all # => [#
class B < A; end # новый класс, наследующий A
B.all # => []
B.new; B.all # => [#
Однако всего одна собака может сделать из переменной экземпляра класса переменную класса, которая у наследников сохраняется, и собирает объекты не только конкретного класса, но и всех его наследников:
class C # Кроме комментариев класс ПОЧТИ идентичен классу A из примера выше
def initialize
self.class.all << self
end
def self.all
@@all ||= [] # Но тут уже не @all
end
end
class D < C; end
D.new; C.new; C.all # => [#
Бонус, для самостоятельного изучения интересующимися, одно не очень хорошее решение:
class M
def initialize
self.class.all << self
end
@all = []
class << self
attr_reader :all
end
end
class N < M; end
M.all # => []
N.all # => nil <-- вот это поворот
Комментариев нет:
Отправить комментарий