2013-05-18 84 views
2

如果我有一個類Salad與方法chew和我使用super它,它會調用下一個可用的chew方法可用上去的祖先鏈。如果我想「達到兩個等級」(到第二個可用的chew方法上漲)怎麼辦?在沒有將super添加到第一個祖先的方法的情況下,有什麼辦法可以做到這一點?紅寶石對象可以在「祖父母」上超級呼叫嗎?

爲了使這個多一點具體的,假設這是我Salad級帶salad對象:

class Salad < Food 
    include Almonds 
    include Gorgonzola 
    include Spinach 
    include Dressing 

    def chew 
    super 
    end 
end 

salad = Salad.new 

祖先的陣列會是這樣的:

[Salad, Dressing, Spinach, Gorgonzola, Almonds, Food, Object, Kernel, BasicObject] 

如果我想要salad.chew觸發chew方法Spinach而不添加super來敷料#咀嚼,這是可能的嗎?有沒有辦法達到兩個層面(就像super「達到」一個層面一樣)?

+1

你有那說明了爲什麼*您正在試圖做你想要做什麼更具體的例子*? –

+1

例如,如果我可以回答,按照程序員想要的方式來解決繼承菱形的線性化問題。 –

回答

4

是的,有一種方法可以做到你所描述的,而這種方式是通過方法#method#instance_method,如method = Spinach.instance_method(:chew),然後你就可以綁定到沙拉,或沙拉實例元類,如method.bind(Salad)。這種機制並不像使用便捷關鍵字super那麼簡單,但提供了super功能的超集。還有一些細節,但相信我,這樣,你可以做任何你想做的事情。這就是Ruby的力量 - 你可以做任何事情,直到對於Lispiest的魔法,你需要Ripper和(迄今未完成的)Sorcerer

(對於使用示例,請參閱我在Using the Object.inspect/Object.to_s on a class derived from Hash其他答案)

1

不,沒有辦法做你正在描述的事情(並且有很好的理由)。您所描述的任何使用「超級超級」關鍵字都會與繼承鏈的細節(以及該鏈中的哪些類/模塊實現給定方法)緊密耦合。它會非常脆弱;如果存在這樣一個關鍵字,並且您使用了它,那麼像移動方法定義這樣的小改動將很容易破壞事物。你的代碼的讀者也會感到困惑。

關鍵字super的用途是:您可以接受一個類,對其進行子類化,重寫一個方法,併爲該方法添加一些新行爲,同時仍然執行該方法原來所做的一切。 super有效地說:「現在執行此方法的默認行爲」。無論這個「默認」行爲是在超類,超超類,模塊還是其他任何地方定義的,這都是有效的。

1

如果您想知道如何實現在所有模塊上調用chew方法,有一個更好的解決方案是使用組合。模塊是爲了行爲,如果你想到你的沙拉課,你不希望它像菠菜或杏仁一樣行事,你希望它是由它們組成的。所以當你chew沙拉你chew其每個組件。

+0

-1,這是可能的。 –