2013-06-25 71 views
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

如果你只是想Person所有實例的列表,你不需要他們在創建補充。只需訪問他們:

ObjectSpace.each_object(Person).to_a 
+0

沒錯。感謝這 - 幫助很多.. – user1541542

+0

+1教學noobs'each_object'。但是我必須警告你在這裏展示的方法 - 它不適用於例如。參數化子類。 –

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">] 
+1

你能解釋一下你說什麼「它不會阻止垃圾收集」嗎? –

+1

爲了完整性,我會說即使@ Frog的答案允許垃圾收集,如果_class本身_是垃圾收集在適當的時間 - 我在談論參數化的子類化,其中人的匿名子類存儲在某個容器對象和用於構建與該容器有關的Person實例。一旦容器消失了,或者不再需要它的'Person',參數化子類本身就被丟棄,所有實例隨後被GC化,因爲引用它們的屬於子類的數組消失了。 –

+1

@YuanhangGuo想象一下這段代碼:'def ghost; p Person.new(「nobody」); end'。調用此方法將創建一個新的Person實例,然後在退出該方法時不再需要該人員。如果沒有上面的代碼,你可以調用這個方法10,000,000次而不會出現內存問題,因爲每個實例最終都會被垃圾回收。但是,使用上面的代碼時,引用將保留給'@ all'數組中的每個實例,因此它們可能永遠不會被移出內存。 – Phrogz

1

我,強制性,將在這裏介紹my 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_assigned鉤子由Ruby核心開發者提供)之前,即搜索整個ObjectSpace - 但不是針對母對象的實例,而是針對名稱空間(Module類對象),其常量被搜索到未命名的實例被分配給他們。

+0

我喜歡.instance_names - 我寧願不安裝更多的寶石。有沒有辦法訪問沒有這個寶石名稱='裏克'的人? – user1541542

+0

我能理解你的感受。擁有太多的依賴關係是不好的。這個寶石提供的獨特之處在於能夠通過賦值給常量命名對象:'Rick = Person.new'。其他的只是普通的普通Ruby編碼。隨意將代碼複製並粘貼到您的項目中。 –

+0

@ user1541542:但我可以向你保證,我正在努力使這個由一羣可靠的人維護的寶石,而且我也向你保證,每個Rubyists都需要這個精確的功能。 –