【问题标题】:How to find each instance of a class in Ruby如何在 Ruby 中查找类的每个实例
【发布时间】:2011-09-02 22:58:56
【问题描述】:

有没有办法获取 Ruby 中某个类的所有对象?

澄清一下:

class Pokemon
end

pikatchu = Pokemon.new
charmander = Pokemon.new

那么,有没有一种方法可以检索这两个对象(pikatchucharmander)的引用?

我实际上想过通过初始化将它全部放入一个类数组中,但这可能会变得很大,我假设可能有一个原生的 Ruby 方法。

【问题讨论】:

    标签: ruby reflection


    【解决方案1】:

    解决办法是使用ObjectSpace.each_object之类的方法

    ObjectSpace.each_object(Pokemon) {|x| p x}
    

    产生

    <Pokemon:0x0000010098aa70>
    <Pokemon:0x00000100992158>
     => 2 
    

    详情在PickAxe book第25章讨论

    【讨论】:

      【解决方案2】:

      是的,可以使用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>] 
      

      【讨论】:

      • 代替 sefl.class.public_send(..),类
      • @earth2jason,这将引发异常(但只是因为拼写错误:-))
      【解决方案3】:

      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
      

      【讨论】:

        【解决方案4】:

        稍作调整,这可能是使用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">]
        

        【讨论】:

          猜你喜欢
          • 2014-12-07
          • 2010-12-26
          • 2015-08-27
          • 2018-10-18
          • 2013-05-02
          • 2011-09-03
          • 2014-02-26
          • 2012-03-17
          • 1970-01-01
          相关资源
          最近更新 更多