Comment puis-je lister tous les objets créés à partir d'une classe de Ruby? [dupliquer]
cette question a déjà une réponse ici:
y a-t-il un moyen dans Ruby pour qu'une classe sache combien de cas il existe et peut-elle les énumérer?
Voici une classe d'échantillon:
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
maintenant je crée des objets de projet de cette classe:
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)
ce que je voudrais c'est avoir des méthodes de classe comme Project.all
et Project.count
pour retourner une liste et un compte de projets en cours.
Comment faire?
4 réponses
vous pouvez utiliser le module ObjectSpace
pour ce faire, en particulier la méthode each_object
.
ObjectSpace.each_object(Project).count
Pour être complet, voici comment vous pourriez utiliser dans votre classe (hat tip pour sawa)
class Project
# ...
def self.all
ObjectSpace.each_object(self).to_a
end
def self.count
all.count
end
end
une façon de le faire est de garder une trace au fur et à mesure que vous créez de nouvelles instances.
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
Si vous voulez utiliser ObjectSpace
, puis son
def self.count
ObjectSpace.each_object(self).count
end
def self.all
ObjectSpace.each_object(self).to_a
end
class Project
def self.all; ObjectSpace.each_object(self).to_a end
def self.count; all.length end
end
peut-être que ça marchera:
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
mais vous devrez détruire manuellement ces objets. Peut-être que d'autres solutions peuvent être construites sur la base du module ObjectSpace.