2012-01-06 97 views
0
class Appointment 
    def self.listen_to(*methods) 
    methods.each do |method_sym| 
     mth = method(method_sym) # <- doesn't find method `something` 
     define_method(method_sym) do 
     print "<listen>#{mth.call}</listen>" 
     end 
    end 
    end 

    def something 
    print "doing something" 
    end 

    listen_to :something 
end 

Undefined method 'something' for class 'Class'。問題似乎是method(:somesymbol)在類的作用域中查找,而不是在該方法的實例作用域中查找。從類範圍內訪問實例範圍

如何從def self.listen_to -class方法中訪問something-方法?

回答

2

您需要使用instance_method,不method

mth = instance_method(method_sym) 

不是問題的一部分,但包裝方法的手段將是一個更大的問題。我使用alias_method重命名舊方法,並使用send來調用它。

> class Appointment 
* def self.listen_to(*methods) 
*  methods.each do |sym|  
*  new_sym = "__orig_#{sym}".to_sym  
*  alias_method new_sym, sym  
*  mth = instance_method(sym) # <- doesn't find method `something`  
*  define_method(sym) do  
*   "<listen>#{send new_sym}</listen>"   
*  end   
*  end  
* end  
* 
* def something 
*  "doing something"  
* end  
* 
* listen_to :something 
* end 
> puts Appointment.new.something 
<listen>doing something</listen> 
+0

謝謝!這解決了我原來的問題(製作包裝方法),但不完全是這個問題中使用的方法。它現在說''call'對於'#'是未定義的。我需要做些什麼才能使它工作? – kornfridge 2012-01-06 14:11:52

+0

@kornfridge查看更新後的答案。 – 2012-01-06 14:13:33

+0

這可以解決問題。公認。再次感謝 – kornfridge 2012-01-06 14:16:05