This question already has an answer here:
这个问题在这里已有答案:
- How to find each instance of a class in Ruby 1 answer
- 如何在Ruby 1中找到每个类的实例答案
Is there any way in Ruby for a class to know how many instances of it exist and can it list them?
有没有办法在Ruby中让一个类知道它有多少个实例并且可以列出它们?
Here is a sample class:
这是一个示例类:
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
Now I create project objects of this class:
现在我创建这个类的项目对象:
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)
What I would like is to have class methods like Project.all
and Project.count
to return a listing and count of current projects.
我想要的是让Project.all和Project.count等类方法返回当前项目的列表和计数。
How do I do this?
我该怎么做呢?
4 个解决方案
#1
42
You can use the ObjectSpace
module to do this, specifically the each_object
method.
您可以使用ObjectSpace模块执行此操作,特别是each_object方法。
ObjectSpace.each_object(Project).count
For completeness, here's how you would use that in your class (hat tip to sawa)
为了完整起见,这里是你如何在课堂上使用它(帽子提示sawa)
class Project
# ...
def self.all
ObjectSpace.each_object(self).to_a
end
def self.count
all.count
end
end
#2
5
One way to do is to keep track of it as and when you create new 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
If you want to use ObjectSpace
, then its
如果你想使用ObjectSpace,那么它
def self.count
ObjectSpace.each_object(self).count
end
def self.all
ObjectSpace.each_object(self).to_a
end
#3
4
class Project
def self.all; ObjectSpace.each_object(self).to_a end
def self.count; all.length end
end
#4
2
Maybe this will work:
也许这会奏效:
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
But you will have to manually destroy these objects. Maybe other solution can be build based on ObjectSpace module.
但是你必须手动销毁这些对象。也许可以基于ObjectSpace模块构建其他解决方案。
#1
42
You can use the ObjectSpace
module to do this, specifically the each_object
method.
您可以使用ObjectSpace模块执行此操作,特别是each_object方法。
ObjectSpace.each_object(Project).count
For completeness, here's how you would use that in your class (hat tip to sawa)
为了完整起见,这里是你如何在课堂上使用它(帽子提示sawa)
class Project
# ...
def self.all
ObjectSpace.each_object(self).to_a
end
def self.count
all.count
end
end
#2
5
One way to do is to keep track of it as and when you create new 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
If you want to use ObjectSpace
, then its
如果你想使用ObjectSpace,那么它
def self.count
ObjectSpace.each_object(self).count
end
def self.all
ObjectSpace.each_object(self).to_a
end
#3
4
class Project
def self.all; ObjectSpace.each_object(self).to_a end
def self.count; all.length end
end
#4
2
Maybe this will work:
也许这会奏效:
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
But you will have to manually destroy these objects. Maybe other solution can be build based on ObjectSpace module.
但是你必须手动销毁这些对象。也许可以基于ObjectSpace模块构建其他解决方案。