好的,所以我一直在我的小Rails應用程序中重構我的代碼,以消除重複,並且通常讓我的生活更輕鬆(因爲我喜歡輕鬆的生活)。這個重構的一部分,一直是將我的兩個模型共同的代碼移動到一個模塊中,我可以將其包含在我需要的模塊中。Ruby mixins和調用超級方法
到目前爲止,這麼好。看起來它會解決問題,但我剛剛遇到一個問題,我不知道如何解決。該模塊(我稱之爲「可發送」)只是處理傳真,電子郵件或打印文檔PDF的代碼。所以,例如,我有一個採購訂單,並且我有內部銷售訂單(想象力縮寫爲ISO)。
我打的問題,是我想要一些變量初始化(初始化的人誰不正確拼寫:P)的對象加載後,所以我一直在使用after_initialize掛鉤。沒問題...直到我開始添加更多mixin。
我的問題是,我可以在我的混入的任何一個的after_initialize
,所以我需要包括在開始一個超級通話,以確保其他混入after_initialize
調用被調用。這真是太棒了,直到我最終打電話給超級電話,並且因爲沒有超級電話而出現錯誤。
這裏有一個小例子,如果我沒有被混淆不夠:
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize(params = nil)
super
self.created_at ||= Time.now.to_date
end
end
所以,如果混入的每一個有after_initialize調用,具有超級電話,我怎麼能阻止那最後超級打電話提高錯誤?在我叫它之前,如何測試超級方法的存在?
Downvoted,因爲它不是一個通用的解決方案。關鍵是你不知道超級是否存在,所以如果將ActiveRecord :: Base#after_initialize存在,你可以創建一個點,當你的代碼在/當ActiveRecord添加一個Base#after_initialize或者它的arity被改變時;如果它被定義,那麼有條件地調用它是遠遠不夠的。 – yaauie 2012-04-03 00:15:10
@yaauie - 當然,我可以在monkeypatch之前加一個`raise'oh no',如果方法.include?(:after_initialize)`,但這會讓這個例子更難理解......很容易陷入困境在詳細說明所有邊界情況下,這裏的實際課程(只是修補一個基本方法)將會在噪聲中迷失方向。 – 2012-04-11 00:29:33