2015-12-14 102 views
2

我碰到這個解決方案爲代理類the Ruby koans傳來:方法執行時不調用它?

class Proxy 
    attr_accessor :messages 

    def initialize(target_object) 
    @object = target_object 
    @messages = [] 
    end 
    def method_missing(method_name, *args, &block) 
    @messages << method_name 
    @object.send(method_name, *args, &block) 
    end 
end 

我可以通過傳遞另一個類作爲參數創建這個代理類的對象。例如,下面的代碼將導致"Do something",而不必鍵入thing.method_missing(:do_thing)

class Thing 
    def do_thing 
    puts "Doing something." 
    end 
end 

thing = Proxy.new(Thing.new) 
thing.do_thing 

爲什麼在method_missing代碼執行,甚至無需調用該方法?

+0

你看過'method_missing'的文檔嗎? http://ruby-doc.org/core-2.2.3/BasicObject.html#method-i-method_missing –

+0

P.S.這是一個實例方法,而不是一個類方法。 –

+0

「當obj發送它無法處理的消息時,由Ruby自動調用」。是的,這是完美的,謝謝! –

回答

4

當某個事件發生或某個方法被調用時,有些方法是隱含調用的(即,即使不在代碼中寫入也會調用)。我將這些方法稱爲掛鉤,借用e-lisp的術語。據我所知,Ruby有以下掛接:

紅寶石鉤

at_exit 
set_trace_func 
initialize 
method_missing 
singleton_method_added 
singleton_method_removed 
singleton_method_undefined 
respond_to_missing? 
extended 
included 
method_added 
method_removed 
method_undefined 
const_missing 
inherited 
initialize_copy 
initialize_clone 
initialize_dup 
prepend 
append_features 
extend_features 
prepend_features 

而且method_missing就是其中之一。對於這個特定的,當Ruby找不到定義的方法時自動調用它。或者換句話說,對於任何方法調用,method_missing是最低優先級調用的最默認方法。

1

method_missing是在紅寶石metaprogramming的驚人的方面之一。正確使用這種方法,你可以優雅地處理異常和不適。在你的情況下,它會被調用,因爲你正在調用的對象的方法顯然不存在。

但是也應該小心使用它。當你在它的時候也要看responds_to方法。

有關ActiveRecord的示例將使您更好地理解。當我們寫:

User.find_by_email_and_age('[email protected]', 20) 

實際上沒有一個名稱的方法。這個電話轉到method_missing,然後這個花式的find方法被分解成幾部分,你得到你要求的東西。我希望有所幫助。

+0

另一個考慮:''method_missing'可以成爲調試的承擔者,'SystemStackError:堆棧層太深'是一個不變的副詞。 –

相關問題