Class: CallTracker

Inherits:
Object show all
Defined in:
lib/drumherum/call_tracker.rb

Overview

oreilly.com/catalog/9780596523695/ Ruby Cookbook, by Lucas Carlson and Leonard Richardson Copyright 2006 O’Reilly Media

Instance Method Summary collapse

Constructor Details

#initialize(show_stack_depth = 1) ⇒ CallTracker

Initialize and start the trace.



11
12
13
14
15
16
# File 'lib/drumherum/call_tracker.rb', line 11

def initialize(show_stack_depth=1)
  @show_stack_depth = show_stack_depth
  @to_trace = Hash.new { |h,k| h[k] = {} }
  start
  at_exit { stop }
end

Instance Method Details

#register(klass, method_symbol) ⇒ Object

Register a class/method combination as being interesting. Subsequent calls to the method will be tallied by tally_calls.



20
21
22
# File 'lib/drumherum/call_tracker.rb', line 20

def register(klass, method_symbol)  
  @to_trace[klass][method_symbol] = {}
end

#report(out = $stderr) ⇒ Object

Prints a report of the lines of code that called interesting methods, sorted so that the the most active lines of code show up first.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/drumherum/call_tracker.rb', line 52

def report(out=$stderr)
  first = true
  @to_trace.each do |klass, symbols|
    symbols.each do |symbol, calls| 
      total = calls.inject(0) { |sum, ct| sum + ct[1] }        
      padding = total.to_s.size
      separator = (klass.is_a? Class) ? '#' : '.'
      plural = (total == 1) ? '' : 's'
      stack_join = "\n" + (' ' * (padding+2))
      first ? first = false : out.puts
      out.puts "#{total} call#{plural} to #{klass}#{separator}#{symbol}"
      (calls.sort_by { |caller, times| -times }).each do |caller, times|
        out.puts " %#{padding}.d #{caller.join(stack_join)}" % times
      end       
    end
  end
end

#startObject

Tells the Ruby interpreter to call tally_calls whenever it’s about to do anything interesting.



26
27
28
# File 'lib/drumherum/call_tracker.rb', line 26

def start
  set_trace_func method(:tally_calls).to_proc
end

#stop(out = $stderr) ⇒ Object

Stops the profiler, and prints a report of the interesting calls made while it was running.



32
33
34
35
# File 'lib/drumherum/call_tracker.rb', line 32

def stop(out=$stderr)
  set_trace_func nil
  report(out)
end

#tally_calls(event, file, line, symbol, binding, klass) ⇒ Object

If the interpreter is about to call a method we find interesting, increment the count for that method.



39
40
41
42
43
44
45
46
47
# File 'lib/drumherum/call_tracker.rb', line 39

def tally_calls(event, file, line, symbol, binding, klass)
  if @to_trace[klass] and @to_trace[klass][symbol] and 
  (event == 'call' or event =='c-call')
    stack = caller
    stack = stack[1..(@show_stack_depth ? @show_stack_depth : stack.size)]
    @to_trace[klass][symbol][stack] ||= 0
    @to_trace[klass][symbol][stack] += 1
  end    
end