2014-10-31 94 views
0

我有一個簡單的模塊和3類:紅寶石:分配另一個內存包括模塊變量

module InitSubclass 
    @@subclass_instances = [] 

    def initialize 
     super 
     @@subclass_instances << self 
    end 

    def self.instances? 
     @@subclass_instances 
    end 
end 

class Animal 
    attr_reader :type 
    @@animal_instances = [] 

    def self.instances? 
     @@animal_instances 
    end 

    def initialize 
     @type = self.class 
     @@animal_instances << self 
     puts "A new #{self} has been instantiated." 
    end 

end 

class Cow < Animal 
    include InitSubclass 
end 

class Dog < Animal 
    include InitSubclass 
end 

現在我運行:

cow = Cow.new 
puts cow.type 
dog1 = Dog.new 
dog2 = Dog.new 

puts Animal.instances?.inspect 
puts Cow.instances?.inspect 
puts Dog.instances?.inspect 

和輸出:

A new #<Cow:0x000000028520a8> has been instantiated. 
Cow 
A new #<Dog:0x00000002851f40> has been instantiated. 
A new #<Dog:0x00000002851e78> has been instantiated. 
[#<Cow:0x000000028520a8 @type=Cow>, #<Dog:0x00000002851f40 @type=Dog>, #<Dog:0x0 
0000002851e78 @type=Dog>] 
[#<Cow:0x000000028520a8 @type=Cow>, #<Dog:0x00000002851f40 @type=Dog>, #<Dog:0x0 
0000002851e78 @type=Dog>] 
[#<Cow:0x000000028520a8 @type=Cow>, #<Dog:0x00000002851f40 @type=Dog>, #<Dog:0x0 
0000002851e78 @type=Dog>] 

這意味着它使用相同的@@ subclass_instances變量。如果我的代碼模塊複製和我所有的子類中重複它正常工作:

A new #<Cow:0x000000028520a8> has been instantiated. 
Cow 
A new #<Dog:0x00000002851f40> has been instantiated. 
A new #<Dog:0x00000002851e78> has been instantiated. 
[#<Cow:0x000000028520a8 @type=Cow>, #<Dog:0x00000002851f40 @type=Dog>, #<Dog:0x0 
0000002851e78 @type=Dog>] 
[#<Cow:0x000000028520a8 @type=Cow>] 
[#<Dog:0x00000002851f40 @type=Dog>, #<Dog:0x00000002851e78 @type=Dog>] 

我怎麼能告訴它分配另一個變種每一個包括模塊? 謝謝。

回答

1

如果您的總體目標僅僅是追蹤任何和所有動物的實例,那麼您可以在沒有該模塊的情況下執行此操作。

class Animal 
    attr_reader :type 

    def self.instances 
    @instances ||= [] 
    end 

    def initialize 
    @type = self.class 
    self.class.instances << self 
    self.class.superclass.instances << self 
    puts "A new #{self} has been instantiated." 
    end 
end 

class Cow < Animal 
end 

class Dog < Animal 
end 

執行時:

A new #<Cow:0x3c7bc48> has been instantiated. 
Cow 
A new #<Dog:0x3c7bab0> has been instantiated. 
A new #<Dog:0x3c7b9f0> has been instantiated. 
Dog instances: 

[#<Cow:0x3c7bc48 @type=Cow>, #<Dog:0x3c7bab0 @type=Dog>, #<Dog:0x3c7b9f0 @type=Dog>] 
[#<Cow:0x3c7bc48 @type=Cow>] 
[#<Dog:0x3c7bab0 @type=Dog>, #<Dog:0x3c7b9f0 @type=Dog>] 

也可以通過模塊來獲取此功能。和最後一個例子一樣,目標是在類本身上設置實例變量(特別是在該類的eigenclass上)。另外,因爲我們需要類方法和實例方法,所以我們使用一些小技巧來包含和擴展。

module InitSubclass 
    def self.included base 
    base.extend InitEigenSubclass 
    end 

    def initialize 
    super 
    self.class.instance_variable_set(:@instances, (self.class.instance_variable_get(:@instances) || [])<< self) 
    end 

    module InitEigenSubclass 
    def instances 
     @instances 
    end 
    end 
end 
+0

它更像是一個「包含」問題......我如何告訴它爲每個包含模塊分配另一個變量?謝謝 – RaduGabor 2014-11-05 12:14:15

+0

對不起,@RaduGabor,我不確定你要完成什麼。我也使用模塊添加了一個解決方案。 – 2014-11-05 21:57:41