在class_eval块中的define_method中使用“send”方法

时间:2013-05-29 08:53:58

标签: ruby ruby-on-rails-3

我在CodeSchool教程中遇到了以下代码:

class MethodLogger

 def log_method((klass,method_name)
  klass.class_eval do
   alias_method "#{method_name}_original" method_name
   define_method method_name do
    puts "#{Time.now}: Called #{method_name}"
    send "#{method_name}_original"
   end
  end
 end

end

如何判断此代码​​中“send”方法的接收器是什么?这里,教程说“klass”表示的类是“send”方法的接收者。 如果是这样的代码:

class Klass
end
k = Klass.new
k.send :hello,  

很明显,k是发送的接收者,主要是发送者。但在第一个代码示例中,我如何推断接收器?

2 个答案:

答案 0 :(得分:2)

接收方是self

的当前值

所以你可以这样做:

class MethodLogger
 def log_method((klass,method_name)
  klass.class_eval do
   alias_method "#{method_name}_original" method_name
   define_method method_name do
    puts "#{Time.now}: Called #{method_name} on #{self.class}"
    send "#{method_name}_original"
   end
  end
 end
end

过了一段时间,你会学会在脑海中跟踪self:)

答案 1 :(得分:1)

在这种情况下,将在self上调用send,这将是klass的实例。默认情况下,如果未指定方法的接收方,则它将为self,如果self上的方法没有这样命名,则Kernel模块将成为接收方。因此,在这种情况下,相关的行将等同于:

self.send "#{method_name}_original"