2009-08-13 131 views
3

我一直在看一些文章,說0123'。他們建議使用元類(或單例類)。這是我的示例代碼Ruby:元類和類變量

class Joe 
    class << self # here we're putting methods in Joe's "meta class" 
    attr_accessor :foo 
    end 
    def self.foo2 
    end 
    def self.foo2=value 
    end 
end 

puts Joe.singleton_methods 

據我所知,foo和foo2的基本上是相同的,雖然沒有辦法與foo2的使用attr_accesor。

我不明白class << self syntax。是否有某種連接發生,或者......它是什麼?這是一種擴展,繼承或猴子修補嗎?

編輯(獎金):雖然我在這裏,有什麼辦法緩存視圖助手的數據?我曾嘗試使用這個類< <自己的事情,但輔助方法找不到訪問器。

+0

就意識到我不得不關閉級高速緩存,以獲得傭工緩存類瓦爾他們的價值觀。比我想象的容易。 – 2009-08-13 14:31:09

回答

10

class<< foo語法代表 「在類的foo的定義」。所以,如果你這樣做:

class Foo 
    class << self 
    # class method defined as INSTANCE method 
    # the only instance being Foo (the class) 
    def boo 
     ... 
    end 
    end 
end 

這類似於

class Foo 
    def self.boo #class method 
    end 
end 

本着同樣的精神,你可以抓住一個單獨的對象與方法擴展它

class << some_object 
    def something # adds a method to some_object ONLY 
    end 
end 

所以,當你在類定義中做「自我內部類」,你可以跳到「一級」 到你的「特徵」類(或「元類」)的定義中,你可以在上下文中調用東西 你的「班級作爲我所處的這個東西的一個實例」。所以你的類的 類方法成爲實例方法並且可以被定義和對待,並且 模塊包含將影響類方法的實例方法。

對於您的情況:

class Joe 
    # here we're putting methods in the "class of class" 
    class << self 
    include ClassMethodsForJoe 
    attr_accessor :foo 
    end 
end 
Joe.foo # this is the method we made 
+0

WOW。這是我需要的答案。 – 2009-08-13 18:59:56

+0

很好的答案。你從一開始,'「class << foo」代表「在foo的定義中」。 @ sepp2k在他的回答中說:「class << foo'打開foo的單例類...」(人們經常看到的表達式)。這些對我來說都有點模糊。難道說「階級」foo使自己等於foo的單身階級「是否更準確? – 2013-10-04 19:10:02

+0

我已經這樣做了,因爲一旦你知道什麼是「特徵類」或「單身類」,你不會問這樣的問題。我發現這兩個概念只對那些已經知道他們在Ruby中意味着什麼的人有用 - 而且我發現他們在解釋整個Class類構造時沒有幫助。 – Julik 2013-10-05 20:32:47

6

class << foo打開foo的單例類,它是foo是唯一實例(並且隱含地繼承了foo的「真實」類)的類。所以這是一種擴展(您正在將方法添加到未由該對象的類定義的特定對象)。這不是猴子補丁,因爲你隻影響一個對象而不是該類的任何其他對象。

注意def foo.bar僅僅是

class <<foo 
    def bar 

即,它在幕後同樣的事情的捷徑。 <<<<方法無關。這只是語法的一部分。

+0

很酷,謝謝。我用獎金編輯了這個問題(真的不用在另一個問題中再次解釋我自己了)......我怎麼能在視圖助手中使用它。 – 2009-08-13 12:40:51

1

說到在視圖幫助器中緩存數據,您可以使用memoization

+0

我現在明白了。但更重要的是,我需要關閉配置中的緩存。 – 2009-08-13 14:25:52