有没有办法在Ruby中获取某个类的所有对象?
澄清:
class Pokemon
end
pikatchu = Pokemon.new
charmander = Pokemon.new
那么,有没有办法可以以某种方式检索这两个对象的引用(pikatchu
和charmander
)?
我实际上想过通过初始化把它全部推到一个类数组中,但这可能会变大,我假设可能有一个原生的Ruby方法。
答案 0 :(得分:28)
解决方案是使用{/ 1}}方法,如
ObjectSpace.each_object
产生
ObjectSpace.each_object(Pokemon) {|x| p x}
详情在PickAxe book第25章
中讨论答案 1 :(得分:2)
ObjectSpace
是一个简单的解决方案,但请注意,您只能对其进行添加;删除对象需要进行垃圾收集,并且可能会变得凌乱。
这是一个跟踪类成员的示例,可让您清除计数。例如,在为规范编写虚拟类时,这可能很有用。
class Foo
@@instances = []
def initialize
@@instances << self
end
def self.clear
@@instances.clear
end
def self.all
@@instances
end
end
用法:
(1..10).each { Foo.new }
Foo.all.size # 10
Foo.clear
Foo.all.size # 0
答案 2 :(得分:0)
是的,人们可以使用ObjectSpace
,但实际上,人们只会在创建实例时跟踪它们。
class Pokemon
@pokees = []
self.class.public_send(:attr_reader, :pokees)
def initialize
self.class.pokees << self
end
end
pikatchu = Pokemon.new
#=> #<Pokemon:0x00005c46da66d640>
charmander = Pokemon.new
#=> #<Pokemon:0x00005c46da4cc7f0>
Pokemon.pokees
#=> [#<Pokemon:0x00005c46da66d640>, #<Pokemon:0x00005c46da4cc7f0>]
答案 3 :(得分:0)
稍作调整,这可能是使用Enumerator#to_a
的好时机:
Pokemon.new("Charmander")
#=> #<Pokemon:0x00007fe4226658d8 @name="Charmander">
Pokemon.new("Sandshrew")
#=> #<Pokemon:0x00007fe424822cf0 @name="Sandshrew">
ObjectSpace.each_object(Pokemon).to_a
#=> [#<Pokemon:0x00007fe4226658d8 @name="Charmander">, #<Pokemon:0x00007fe424822cf0 @name="Sandshrew">]