simha
simha

Reputation: 574

Using "send" method inside define_method in class_eval block

I have come across the following code in CodeSchool tutorial:

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

How can I tell what is the receiver for the "send" method in this code ? Here, the tutorial says that the class represented by "klass" is be the receiver of the "send" method. In case of code like this :

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

It is obvious that k is the receiver of send and main is the sender . But in the first code sample , how can I deduce the receiver ?

Upvotes: 1

Views: 611

Answers (2)

ggPeti
ggPeti

Reputation: 875

In this case send will get called on self, which will be an the instance of klass. By default, if the method's receiver is not specified, it will be self, and if there is no method on self named like that, the Kernel module will be the receiver. So in this case, the line in question will be equivalent to:

self.send "#{method_name}_original"

Upvotes: 1

Louis Kottmann
Louis Kottmann

Reputation: 16618

The reciever is the current value of self

So you can do:

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

After a while you'll learn to keep track of self in your mind :)

Upvotes: 2

Related Questions