2012-01-06 9 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)がクラスのスコープ内にあり、メソッドのインスタンススコープ内では見えないようです。クラススコープ内からのインスタンススコープへのアクセス

somethingの方法はdef self.listen_to -classmethodからアクセスできますか?

答えて

2

あなたはmethodinstance_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

+0

@kornfridge更新された回答を参照してください。 –

+0

これは問題を解決/解決します。受け入れられました。再度、感謝します – kornfridge

関連する問題