2013-01-14 14 views
27

Bir sınıf için Ruby'nin kaç örnek olduğunu bilmesi ve listeleyebilmesi için herhangi bir yolu var mı? Ben istiyorum neBir sınıftan oluşturulan tüm nesneleri Ruby'de nasıl listeleyebilirim?

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) 

bir liste dönmek için Project.all ve Project.count gibi sınıf yöntemleri sahip olmaktır:

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 

Şimdi bu sınıfın proje nesneleri oluşturmak: Burada

örnek bir sınıftır ve mevcut projelerin sayısı.

Bunu nasıl yaparım?

cevap

40

Bunu yapmak için ObjectSpace modülünü, özellikle de each_object yöntemini kullanabilirsiniz.

ObjectSpace.each_object(Project).count 

bütünlüğü için, burada bu ne yaparım olduğunu

class Project 
    # ... 

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

    def self.count 
    all.count 
    end 
end 
+0

Çalışması için sınıfta 'ObjectSpace' içermesi gerekiyor mu? – onebree

+2

@HunterStevens hayır, modülü sınıfımıza karıştırmıyoruz, sadece bir yöntem arıyoruz –

+0

** UYARI **: Bu çözüm, kendini ayağından çekmeyi kolaylaştırabilir. Nesnelerinize bir referans tutmazsanız (örneğin, sonucu bir şeye atamadan "Project.new" yaparsanız), bir noktada çöp toplanacak ve "ObjectSpace.each_object" açık bir şekilde bunları bildirmeyi durduracaktır. Rohit89'un cevabı gibi '@@ instances = []' kullanarak, bu nesnelere bir referans vererek bu problemi çözer. – vmarquet

5

Bunu yapmanın bir yolu, yeni örnekler oluşturduğunuzda olduğu gibi izlemektir.

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 

Eğer ObjectSpace kullanmak istiyorsanız

, daha sonra

def self.count 
    ObjectSpace.each_object(self).count 
end 

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

(Sawa için şapka ucu) senin sınıfında kullanacağı nasıl. Tüm Ruby uygulamalarında kesinlikle çalışır ve gerekirse farklı amaçlar için genişletilebilir. –

2

Belki bu işe yarar:

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 

Ama elle bu nesneleri yok etmek zorunda kalacak. Belki başka bir çözüm ObjectSpace modülüne dayanarak oluşturulabilir.

+0

Bunu sevdim ama bazı düşüncede olmalıydı - Bu yakutta var mı? ObjectSpace modülünü nasıl kullanacağım hakkında hiçbir fikrim yok. Örnek gerçekten –

+1

Well yardımcı olur. ObjectSpace, çöp toplayıcı ile etkileşime girmenizi sağlar. Bu benim kodumda yapmamaya çalıştığım şeyler. ObjectSpace.each_object (Project) .to_a' ile deneyebilirsiniz, ancak bununla daha fazla yardımcı olamam. – yattering

+0

bunun neden kaçınılmasının özel bir nedeni? –

4
class Project 
    def self.all; ObjectSpace.each_object(self).to_a end 
    def self.count; all.length end 
end 
İlgili konular