2012-08-07 25 views
0

我想知道是否有可能讓這個,如果我有這樣的事情重寫對象屬性訪問

class Test 

    attr_reader :access_times 
    def initialize 
    @access_times = 0 
    end 

    def get_two 
    2 
    end 

    ... 
end 

t = Test.new 

那對t任何訪問將運行的代碼實際運行的方法實施前的特定部分?

例如,如果我突然決定說t.get_two,我使用了.語法的事實會被1.增加@access_times也許我做了檢查t.is_a?(Test),它也將增加@access_times由1.訪問任何方法或屬性繼承Test也將增加變量1.

基本上我想添加一些東西到.語法如果可能的話。

我不是問這是好還是壞代碼,只是它是否可行以及如何完成。我通常不會使用它,因爲我可以將增量邏輯手動添加到每種方法,並用方法替換所有直接實例變量訪問(甚至像is_a?和其他東西繼承自Object

回答

0

一個漂亮的鐵桿版本是使用set_trace_funchttp://apidock.com/ruby/Kernel/set_trace_func

這使您可以訂閱整個程序觸發的所有紅寶石的事件,它可以是一噸的呼叫......

我不要認爲有註冊到任意方法調用的內置鉤子。你可以實現一些方法缺失,方法鏈接或委託,但這取決於你的需求。

+0

我使用缺少方法作爲臨時解決方案,直到找到一個更好的方法來完成它。將研究鏈接和委派的方法。 – MxyL 2012-08-08 00:38:44

0

如果您不需要一切都是獨立的,一個建議只是擴展ActiveModel::Callbacks。只需擴展該類,就可以擁有before_filter的所有功能,而不需要其他所有Rails的東西。

+0

這隻適用於活動模型的Livecycle回調,不是嗎? – phoet 2012-08-07 19:35:40

+0

我希望它是獨立的,但謝謝你的建議。我沒有爲Rails工作,但我不確定該特定模塊是否可用。 – MxyL 2012-08-07 19:35:59

0

根據您的描述,這是一種解決方法。基本上它會爲每個實例方法增加@access_times,並且該方法也會執行之前的操作。

class Test 
    attr_accessor :access_times 

    def initialize 
    @access_times = 0 
    end 

    def get_two 
    2 
    end 
end 

class Test 
    @@im = instance_methods 

    @@im.each do |m| 
    class_eval <<-END 
     alias temporary #{m} 
    END 

    define_method(m) do |*args, &block| 
     @access_times += 1 
     temporary(*args, &block) 
    end 
    end 

    undef :temporary 
end 

Test.new.get_two # => @access_times += 1 and original get_two is called: 2 

雖然這段代碼不能按預期工作,但稍後我會看看它。謝謝。