Как я могу перечислить все объекты, созданные из класса в Ruby?
Есть ли какой-либо путь в Ruby для класса, чтобы узнать, сколько его экземпляров существует и можно ли их перечислить?
Вот пример класса:
class Project
attr_accessor :name, :tasks
def initialize(options)
@name = options[:name]
@tasks = options[:tasks]
end
def self.all
# return listing of project objects
end
def self.count
# return a count of existing projects
end
end
Теперь я создаю объекты проекта этого класса:
options1 = {
name: 'Building house',
priority: 2,
tasks: []
}
options2 = {
name: 'Getting a loan from the Bank',
priority: 3,
tasks: []
}
@project1 = Project.new(options1)
@project2 = Project.new(options2)
Я бы хотел, чтобы методы класса, такие как Project.all
и Project.count
, возвращали список и количество текущих проектов.
Как это сделать?
Ответы
Ответ 1
Для этого вы можете использовать модуль ObjectSpace
, в частности метод each_object
.
ObjectSpace.each_object(Project).count
Для полноты, вот как вы могли бы использовать это в своем классе (подсказка шляпы к писе)
class Project
# ...
def self.all
ObjectSpace.each_object(self).to_a
end
def self.count
all.count
end
end
Ответ 2
Один из способов сделать это - отслеживать его как при создании новых экземпляров.
class Project
@@count = 0
@@instances = []
def initialize(options)
@@count += 1
@@instances << self
end
def self.all
@@instances.inspect
end
def self.count
@@count
end
end
Если вы хотите использовать ObjectSpace
, то его
def self.count
ObjectSpace.each_object(self).count
end
def self.all
ObjectSpace.each_object(self).to_a
end
Ответ 3
class Project
def self.all; ObjectSpace.each_object(self).to_a end
def self.count; all.length end
end
Ответ 4
Возможно, это сработает:
class Project
class << self; attr_accessor :instances; end
attr_accessor :name, :tasks
def initialize(options)
@name = options[:name]
@tasks = options[:tasks]
self.class.instances ||= Array.new
self.class.instances << self
end
def self.all
# return listing of project objects
instances ? instances.dup : []
end
def self.count
# return a count of existing projects
instances ? instances.count : 0
end
def destroy
self.class.instances.delete(self)
end
end
Но вам придется вручную уничтожить эти объекты. Возможно, другое решение может быть построено на основе модуля ObjectSpace.