从类范围内访问实例范围

时间:2012-01-06 13:52:39

标签: ruby scope metaprogramming

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 - classmethod中访问def self.listen_to - 方法?

1 个答案:

答案 0 :(得分: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>