1
class Person
  attr_accessor :name

  def initialize(name)
     @@name = name
     people.push($)
  end
end

它不必在初始化函数中。我只想创建一个包含所有人员的数组。

p1 = Person.new("joe")
p2 = Person.new("rick")
people.inspect #-->would return [p1, p2]
4

3 回答 3

4

如果您只想要 的所有实例的列表Person,则无需在创建时添加它们。只需通过以下方式访问它们:

ObjectSpace.each_object(Person).to_a
于 2013-06-25T04:28:06.287 回答
2

@sawa 的答案是最好的,因为它不会阻止垃圾收集。如果您确实想在创建每个实例时记录它(并防止对其他未使用的实例进行垃圾收集),您可以简单地:

class Person
  @all = []
  def self.all; @all; end
  attr_accessor :name
  def initialize(name)
    @name = name
    self.class.all << self
  end
end

p1 = Person.new("joe")
p2 = Person.new("rick")
p Person.all
#=> [#<Person:0x007f9d1c8c4838 @name="joe">,
#=>  #<Person:0x007f9d1c8bb0d0 @name="rick">]
于 2013-06-25T04:40:51.053 回答
1

我,强制性地,将在这里介绍NameMagic的:

# first, gem install y_support
require 'y_support/name_magic'

class Person
  include NameMagic
  # here, Person receives for free the following functionality:
  # * ability to use :name (alias :ɴ) named argument in the constructor
  # * #name (alias #ɴ) instance method
  # * #name= naming / renaming method
  # * ability to name anonymous instances by merely assigning to constants
  # * collection of both named and anonymous instances inside the namespace
  # * hooks to modify the name, or do something else when the name is assigned
  # * ability to specify a different namespace than mother class for instance collection
end

Joe = Person.new #=> #<Person:0xb7ca89f8>
Rick = Person.new #=> #<Person:0xb7ca57bc>

Joe.name #=> :Joe
Rick.ɴ #=> :Rick
Person.instances # [#<Person:0xb7ca89f8>, #<Person:0xb7ca57bc>]
Person.instance_names # [:Joe, :Rick]

Person.new name: "Kit" #=> #<Person:0xb9776244>
Person.instance_names #=> [:Joe, :Rick, :Kit]
p3 = Person.instance( :Kit ) #=> #<Person:0xb9776244>
p2 = Person.instance( "Rick" ) #=> #<Person:0xb7ca57bc>
# Also works if the argument is already a Person instance:
p1 = Person.instance( Person.instance( :Joe ) ) #=> #<Person:0xb9515ba8>

anon = Person.new #=> #<Person:0xb9955c54>
Person.instances.size #=> 4
Person.instance_names #=> [:Joe, :Rick, :Kit]
anon.name = :Hugo
Person.instance_names #=> [:Joe, :Rick, :Kit, :Hugo]
Person::Hugo #=> #<Person:0xb9955c54>

对于垃圾收集的担忧,可以忘记实例

Person.forget :Hugo #=> Returns, for the last time, "Hugo" instance
Person::Hugo #=> NameError
Person.forget_all_instances #=> [:Joe, :Rick, :Kit]
Person.instances #=> [] - everything is free to be GCed

NameMagic底层使用与@sawa 提出的相同方法(至少在const_assignedRuby 核心开发人员提供 hook 之前),即搜索整体ObjectSpace——但不是针对母对象的实例,而是针对命名空间(Module类对象),其搜索常量以查找分配给它们的未命名实例。

于 2013-06-25T05:27:44.443 回答