如何在Ruby中列出从类创建的所有对象?

如何在Ruby中列出从类创建的所有对象?,ruby,oop,class-method,Ruby,Oop,Class Method,在Ruby中,有没有办法让一个类知道它有多少个实例,并能列出它们 下面是一个示例类: 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 se

在Ruby中,有没有办法让一个类知道它有多少个实例,并能列出它们

下面是一个示例类:

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
现在,我创建此类的项目对象:

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)
我想要的是像
Project.all
Project.count
这样的类方法来返回当前项目的列表和计数


如何做到这一点?

一种方法是在创建新实例时跟踪它

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
也许这会奏效:

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
类项目

类您可以使用
ObjectSpace
模块来执行此操作,特别是方法

为了完整起见,以下是您在课堂上如何使用它(sawa的帽尖)


我喜欢这样,但是可以有一些内置的反射吗?这在ruby中不存在吗?我不知道如何使用ObjectSpace模块。举个例子会很有帮助。ObjectSpace允许您与垃圾收集器交互。这是我在代码中尽量不做的事情。你可以用
ObjectSpace.each_object(Project).to_a
进行实验,但我不能再帮你了。有什么特别的原因应该避免吗?例如,在中编写的方法
count_objects
是“除了C Ruby之外不应该工作的”。所以你必须小心。
count_objects
只适用于MRI(又名C Ruby)
每个_对象
在MRI、Rubinius和JRuby中工作(在1.9.3版本上测试)。这就是我要做的。它在所有Ruby实现中都能正常工作,如果需要,还可以扩展到不同的用途。你需要在类中包含ObjectSpace吗?@HunterStevens不,我们不是将模块混入类中,只是在类中调用一个方法警告:这个解决方案可以让你很容易自食其果。如果您不保留对对象的引用(例如,如果您在没有将结果分配给某个对象的情况下执行了
Project.new
),它们将在某个点和
ObjectSpace进行垃圾收集。每个对象显然将停止报告它们。使用
@@instances=[]
代替rohit89的答案,通过保留对这些对象的引用来解决这个问题。
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
ObjectSpace.each_object(Project).count
class Project
  # ...

  def self.all
    ObjectSpace.each_object(self).to_a
  end

  def self.count
    all.count
  end
end
class Project
    def self.all; ObjectSpace.each_object(self).to_a end
    def self.count; all.length end
end