How to find each instance of a class in Ruby

后端 未结 4 1026
無奈伤痛
無奈伤痛 2020-12-09 10:30

Is there a way to get all the objects that are of a certain class in Ruby?

To clarify:

class Pokemon
end

pikatchu = Pokemon.new
charmander = Pokemon         


        
相关标签:
4条回答
  • 2020-12-09 11:05

    Slightly adjusted, this is probably a good time to use 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">]
    
    0 讨论(0)
  • 2020-12-09 11:06

    The solution is to use ObjectSpace.each_object method like

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

    which produces

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

    Details are discussed in the PickAxe book Chapter 25

    0 讨论(0)
  • 2020-12-09 11:07

    ObjectSpace is a simple solution, but note that you can only add to it; removing objects requires garbage collection and that can get messy.

    Here's an example of tracking class members that allows you to clear the count. This could be useful, for example, when writing a dummy class for specs.

    class Foo
      @@instances = []
    
      def initialize
        @@instances << self
      end
    
      def self.clear
        @@instances.clear
      end
    
      def self.all
        @@instances
      end
    end
    

    Usage:

    (1..10).each { Foo.new }
    Foo.all.size # 10
    Foo.clear
    Foo.all.size # 0
    
    0 讨论(0)
  • 2020-12-09 11:11

    Yes, one could use ObjectSpace, but in practice one would simply keep track of instances as they are created.

    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>] 
    
    0 讨论(0)
提交回复
热议问题