-
Notifications
You must be signed in to change notification settings - Fork 0
/
call_tracer.rb
53 lines (46 loc) · 1.47 KB
/
call_tracer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# ~/lib/ruby/call_tracer.rb
class CallTracer
def initialize(
log_file=nil, # String: filename
search: nil, # String: substring in path to log
here: '', # String: path prefix to remove
indent: ' ', # String: indention character(s)
editor: 'subl' # Sring: name of a text editor
)
if log_file.nil?
@log = STDOUT
else
@log = File.open(log_file, 'w')
end
@search = search
@here = here
@indent = indent
@trace_point = nil
@call_stack = []
end
def start
@trace_point = TracePoint.new(:call, :return) do |tp|
location = "#{@editor} #{tp.path.gsub(@here,'.')}:#{tp.lineno}"
case tp.event
when :call
event = "#{@indent * @call_stack.size}#{tp.defined_class}##{tp.method_id} #{location}"
@call_stack.push([tp.defined_class, tp.method_id])
when :return
last_call = @call_stack.pop
return_value = tp.return_value.inspect
# Ensure that we are returning from the correct method.
if last_call == [tp.defined_class, tp.method_id]
event = "#{@indent * @call_stack.size}#{last_call[0]}##{last_call[1]} returned #{return_value} #{location}"
end
event = ""
end
if [email protected]? && !event.empty? && location.include?(@search)
@log.puts event
end
end
@trace_point.enable
end
def stop
@trace_point.disable if @trace_point
end
end