2009-05-20 53 views
7

我可以理解爲什麼你需要一個類變量來跟蹤事件,比如在該類中實例化的對象的總數。您是否曾經在任何Ruby代碼中使用過「類實例變量」?

我能理解爲什麼你需要一個實例變量來存儲該類中特定對象的屬性。

類實例變量我似乎無法證明。

據我所知,它們就像類變量一樣,只不過它們是對於子類變量的子類不可見。

看起來這種用法是相當有限的。或者我錯了?有沒有人在他們的代碼中找到類實例變量的很好用處?或者你可以舉一個這種類型的細微差別有價值的情況的例子嗎?

回答

4

說你想算一類(不包括子類)

class A 
    @count = 0 
    @@count = 0 
    def self.inherited(subclass) 
    subclass.instance_eval { @count = 0 } 
    end 
    def self.num_instances 
    @count 
    end 
    def self.num_subclass_instances 
    @@count 
    end 
    def self.new 
    @count += 1 
    @@count += 1 
    super 
    end 
end 
class B < A 
end 
class C < B 
end 

A.new 
B.new 
A.new 
B.new 
B.new 
C.new 

A.num_instances #=> 2 
A.num_subclass_instances #=> 6 
B.num_instances #=> 3 
B.num_subclass_instances #=> 6 
C.num_instances #=> 1 
C.num_subclass_instances #=> 6 

不能使用類變量的實例的數量,因爲這是所有 類之間共享,其子類。請注意0​​ 的BC所做的更改如何反映在A中,但不共享@count

一般來說,它可以非常有用的存儲任何類特定的設置。 _why在Dwemthy's Array中使用它來指定實例屬性的初始值,並且在進行ruby元編程時會出現很多。

+0

謝謝。很好的例子。所以,基本上,如果我們只有類變量,我們將無法做到像A,B和C這些本地化計數的事情 - 我們會被等同於您的num_subclass_instances。我想我現在明白了。你不知道的代碼的唯一部分是:def self.inherited(subclass)subclass.instance_eval {@count = 0} end。這是做什麼的? – 2009-05-21 04:13:30

3

類變量在類的所有實例之間共享,其中包括所有子類。有時候,層次結構中的這個變量恰好是需要的,但有時您可能更喜歡每個類別的不同變量。與類變量不同,類實例變量將爲每個類對象使用不同的值。

http://martinfowler.com/bliki/ClassInstanceVariable.html

3

是的,其實我有。這只是略作修改和修剪,從我有:

class Widget 
    # class instance variable pattern 
    class << self; attr_accessor :color; end 

    def show_color() 
    "This widget is #{self.class.color}" 
    end 
end 
class WidgetR < Widget 
    @color = "Russet" 
end 
class WidgetC < Widget 
    @color = "Cordovan" 
end 
class WidgetL < Widget 
    @color = "Liver" 
end 

WidgetR.new.show_color #=> "This widget is Russet" 

但我不知道它是在我使用它的情況確有必要。我可能只是重寫了這個方法。或者提供了一種顏色方法。或者將其作爲散列存儲在類變量中。或者甚至在每個實例中都保留一個副本(好吧,那個人就是這樣)。我敢肯定還有其他的可能性......

有各種各樣的替代品和語法是尷尬的。鑑於我猜測最自然使用的情況可能相當罕見。

它可能會幫助您嘗試使用類和實例變量重現此行爲,並且發現它很難實現(儘管定義方法等很簡單)。

C.J.

相關問題