Страницы

Поиск по вопросам

вторник, 21 мая 2019 г.

Как в Ruby при создании объекта класса сохранить в массив созданных объектов?

Как в 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 # => [#] A.new; A.all # => [#, #]
class B < A; end # новый класс, наследующий A B.all # => [] B.new; B.all # => [#] A.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 <-- вот это поворот

Комментариев нет:

Отправить комментарий