2011-12-14 51 views
1

以下是可以動態地將日誌記錄添加到方法的類的代碼。這適用於方法不帶參數且不接受任何塊的情況。在Ruby中動態定義方法時,如何處理參數和塊?

如何重寫代碼,以便我可以添加方法的日誌記錄,即使它接受參數並接受一個塊?

class X 
    def greet 
     puts "hi" 
    end 

    def self.add_logging(method_name) 
     alias_method("original_#{method_name}".to_sym, method_name) 

     #How do i rewrie this to account for method_name's arguments and ability to accept a block? 
     define_method(method_name) do 
      puts "calling #{method_name}" 
      send "original_#{method_name}".to_sym 
      puts "done #{method_name}" 
     end 
    end 
end 

x = X.new 
x.greet 
X.add_logging(:greet) 
x.greet 

輸出

>hi 
>calling greet 
>hi 
>done greet 

回答

3
class X 
    def self.add_logging method 
    alias_method "original_#{method}", method 
    define_method(method) do |*args, &pr| 
     puts "calling #{method}" 
     send "original_#{method}", *args, &pr 
     puts "done #{method}" 
    end 
    end 
    def greet person 
    puts "hi #{person}" 
    end 
end 

x = X.new 
x.greet("Joe") 
X.add_logging(:greet) 
x.greet("Jane") 

會給:

hi Joe 
calling greet 
hi Jane 
done greet 
2

據我知道define_method - 方法塊接受參數,它代表該方法的參數,因此我們建議如下:

define_method(method_name) do |*arguments| 
     puts "calling #{method_name}" 
     send "original_#{method_name}".to_sym, *arguments 
     puts "done #{method_name}" 
end 

*arguments在塊中的do部分中包含所有在調用方法method_name時發送的參數/參數到一個數組中,*arguments在send-method調用中再次展開它們以便在原始方法中使用。

+0

對,但我不知道有多少參數當我打電話add_logging原來的方法接受,所以我不能硬編碼的參數,你一個具體的數字已經完成了。我也不知道它是否接受一個區塊,並且想要說明這種可能性。 – z5h 2011-12-14 22:36:09

+0

這適用於每個參數,因爲*參數一次滾動所有參數。 – robustus 2011-12-14 22:40:54

相關問題