Fork me on GitHub

Thursday, July 31, 2008

Ruby: A simple tracer code to track method calls

I was working on a small piece of code and there was need for a tracer code which can find the method being called, in which order and the arguments passed into the method and the value the method returned. The methods were public instance methods and I did not need an heavy or fully functional tracer. So I spent sometime to write a small tracer for myself and give myself a small exercise in metaprogramming. Below the code which came out of it... There may be better ways to do it and I am learning them as I go along my journey of software development and testing code... Pretty long journey I suppose :).


module Tracer
def self.included(klass)
instance_methods = klass.public_instance_methods(false)
instance_methods.each do method
self.hook_method(klass,method)
end
end
def self.hook_method(klass, method)
klass.class_eval do
alias_method "old_#{method}", "#{method}"
define_method(method) do *args
puts "#{method} called" + " with #{args.join(',')}" unless args.nil?
value = self.send("old_#{method}",*args)
puts "#{method} returned #{value}" unless value.nil?
variables = []
self.instance_variables.each do variable
variables << "#{variable} = #{self.instance_variable_get(variable)}"
end
puts "instance variables - #{variables.join(',')}"
return value
end
end
end
end

class Person
def greet(name)
@name = name
@greeting = "hello"
return "#{@greeting} #{@name}"
end
include Tracer
end

Person.new.greet("matz")

No comments: