unroller 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme +25 -16
- data/lib/unroller/unroller.rb +39 -14
- metadata +2 -2
data/Readme
CHANGED
@@ -58,17 +58,9 @@ This is much more efficient and reliable than manually tracing through the execu
|
|
58
58
|
|
59
59
|
===Reducing verbosity
|
60
60
|
|
61
|
-
This can generate some really *verbose* output...
|
61
|
+
This can generate some really *verbose* output... Not only can be impractical to try to *read* through the reams of pages it can produce, but it can also take an hour just to output it in the first place!
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
Unroller::trace do
|
66
|
-
stuff_you_care_about
|
67
|
-
Unroller::exclude do
|
68
|
-
stuff_that_you_really_dont_care_about
|
69
|
-
end
|
70
|
-
stuff_you_care_about
|
71
|
-
end
|
63
|
+
A couple options are available to help things under control. The two main approaches are to only trace a limited section of code or to trace a large section of code but exclude certain types of calls (for example, low-level methods that you don't care about.)
|
72
64
|
|
73
65
|
You may find that your trace is cluttered/dominated by calls to a small set of methods and classes that you don't care about. These options help you to exclude the worst offenders in a hurry:
|
74
66
|
|
@@ -76,20 +68,22 @@ You may find that your trace is cluttered/dominated by calls to a small set of m
|
|
76
68
|
Unroller won't show a trace for any calls to methods from the given class or classes (regular expressions).
|
77
69
|
Pass [/class_name/, :recursive] to also not show the trace for any calls made *from* those uninteresting methods.
|
78
70
|
<tt>:exclude_methods</tt> (not implementd) ::
|
79
|
-
Like <tt>:exclude_classes</tt> only you give it _method_ names instead of class names. Maybe will have the ability to specify a class name as well as a method name if you want to be more specific (f.e., <tt>ThatOneClass#format</tt> if you still want to include calls to other methods named <tt>format
|
71
|
+
Like <tt>:exclude_classes</tt> only you give it _method_ names instead of class names. Maybe will have the ability to specify a class name as well as a method name if you want to be more specific (f.e., <tt>ThatOneClass#format</tt> if you still want to include calls to other methods named <tt>format</tt>).
|
80
72
|
|
81
73
|
These options are for more general overall control:
|
82
74
|
|
83
|
-
<tt>:
|
84
|
-
Use this to prevent from going more than <tt>depth
|
85
|
-
<tt>:
|
75
|
+
<tt>:max_depth => depth</tt> ::
|
76
|
+
Use this to prevent from going more than <tt>depth</tt> levels deep (_relative_ to starting depth) if you find that the trace is cluttered by a bunch of really deep calls.
|
77
|
+
<tt>:max_lines</tt> ::
|
86
78
|
If you don't know where to place the trace(false) and you just want it to stop on its own after so many lines, you could use this...
|
87
79
|
|
80
|
+
I'd recommend using <tt>:max_depth</tt> option with something sane like 3 or 5 most of the time.
|
81
|
+
|
88
82
|
Examples:
|
89
83
|
|
90
|
-
Unroller::trace :
|
84
|
+
Unroller::trace :max_lines => 100, :exclude_classes => /Boring/ { ... }
|
91
85
|
|
92
|
-
Unroller::trace :if => proc{$tracing_enabled}, :
|
86
|
+
Unroller::trace :if => proc{$tracing_enabled}, :max_depth => 9, :exclude_classes =>
|
93
87
|
[
|
94
88
|
/Benchmark/,
|
95
89
|
/Logger/,
|
@@ -107,7 +101,15 @@ Examples:
|
|
107
101
|
...
|
108
102
|
end
|
109
103
|
|
104
|
+
Ignore a section of code that is within the block passed to +trace+:
|
110
105
|
|
106
|
+
Unroller::trace do
|
107
|
+
stuff_you_care_about
|
108
|
+
Unroller::exclude do
|
109
|
+
stuff_that_you_really_dont_care_about
|
110
|
+
end
|
111
|
+
stuff_you_care_about
|
112
|
+
end
|
111
113
|
|
112
114
|
===How did that method even get *called*?
|
113
115
|
|
@@ -175,8 +177,15 @@ It's also sort of like a call stack (caller(0)). But unlike the callstack you us
|
|
175
177
|
|
176
178
|
==To do
|
177
179
|
|
180
|
+
You're welcome to submit comments and/or patches.
|
181
|
+
|
178
182
|
* Make a GUI interface that lets you quickly collapse/nodes nodes of the tree.
|
179
183
|
* It would be nice if we could see what arguments are being passed to each method. This would be technically difficult, but I wonder if it would be possible to just wait for a 'call' event and when you see one, wrap/alias_method_chain the given classname/id with a wrapper method that has variable *args and does whatever you want to do with the args before actually doing the *real* method call....
|
180
184
|
* :include_classes option in addition to :exclude_classes?
|
185
|
+
* Have some "presets" for what you might want to exclude if tracing an ActiveRecord request for example. In that case, you probably don't want to see the internals of any support code, like any methods from ActiveSupport.
|
186
|
+
* :preset => :Rails : Exclude ActiveSupport, etc.
|
187
|
+
* :preset => :ActiveSupport : Exclude ActiveRecord, etc.
|
188
|
+
* :preset => :'ActiveRecord high level' : excludes the lowel-level database stuff (like the individual adapter (SQLite, MySQL, ...).
|
189
|
+
* :preset => :'ActiveRecord low level'
|
181
190
|
|
182
191
|
|
data/lib/unroller/unroller.rb
CHANGED
@@ -36,8 +36,8 @@ class Unroller
|
|
36
36
|
# Defaults
|
37
37
|
@condition = Proc.new { true } # Only trace if this condition is true. Useful if the place where you put your trace {} statement gets called a lot and you only want it to actually trace for some of those calls.
|
38
38
|
@initial_depth = 0 # ("Call stack") depth to start at. Actually, you'll probably want this set considerably lower than the current call stack depth, so that the indentation isn't way off the screen.
|
39
|
-
@
|
40
|
-
@
|
39
|
+
@max_lines = nil # Stop tracing (permanently) after we have produced @max_lines lines of output. If you don't know where to place the trace(false) and you just want it to stop on its own after so many lines, you could use this...
|
40
|
+
@max_depth = nil # Don't trace anything when the depth is greater than this threshold. (This is *relative* to the starting depth, so whatever level you start at is considered depth "1".)
|
41
41
|
@exclude_classes = []
|
42
42
|
@strip_comments = true # :todo:
|
43
43
|
@use_full_path = false # :todo:
|
@@ -113,7 +113,7 @@ class Unroller
|
|
113
113
|
#return if uninteresting_class?(klass.to_s) unless (klass == false)
|
114
114
|
|
115
115
|
if too_far?
|
116
|
-
puts "We've read #{@
|
116
|
+
puts "We've read #{@max_lines} (@max_lines) lines now. Turning off tracing..."
|
117
117
|
trace_off
|
118
118
|
return
|
119
119
|
end
|
@@ -123,7 +123,7 @@ class Unroller
|
|
123
123
|
|
124
124
|
|
125
125
|
when 'call'
|
126
|
-
unless
|
126
|
+
unless skip_line?
|
127
127
|
# :todo: use # instead of :: if klass.constantize.instance_methods.include?(id)
|
128
128
|
column sprintf(' ' + '+'.cyan + ' calling'.cyan + ' ' + '%s::%s'.underline.cyan, klass, id), @column_widths[0]
|
129
129
|
newline
|
@@ -138,9 +138,10 @@ class Unroller
|
|
138
138
|
@depth += 1
|
139
139
|
|
140
140
|
|
141
|
-
|
141
|
+
when 'class'
|
142
|
+
when 'end'
|
142
143
|
when 'line'
|
143
|
-
unless
|
144
|
+
unless skip_line?
|
144
145
|
column code_for(file, line, ' ', :bold), @column_widths[0]
|
145
146
|
file_column file, line
|
146
147
|
newline
|
@@ -155,7 +156,7 @@ class Unroller
|
|
155
156
|
@depth -= 1 unless @depth == 0
|
156
157
|
|
157
158
|
|
158
|
-
unless
|
159
|
+
unless skip_line?
|
159
160
|
code = code_for(file, line, '\\'.magenta, :green)
|
160
161
|
code = code_for(file, line, '\\'.magenta + ' (returning)'.green, :green) unless code =~ /return|end/
|
161
162
|
# I've seen some really weird statements listed as "return" statements.
|
@@ -183,6 +184,7 @@ class Unroller
|
|
183
184
|
|
184
185
|
|
185
186
|
when 'raise'
|
187
|
+
# We probably always want to see these (?)... Never skip displaying them, even if we are "too deep".
|
186
188
|
column "Raising an error (#{$!}) from #{klass}".red.bold, @column_widths[0]
|
187
189
|
newline
|
188
190
|
|
@@ -191,7 +193,7 @@ class Unroller
|
|
191
193
|
newline
|
192
194
|
|
193
195
|
else
|
194
|
-
|
196
|
+
column sprintf("- (%8s) %10s %10s (%s:%-2d)", event, klass, id, file, line)
|
195
197
|
newline
|
196
198
|
end
|
197
199
|
|
@@ -231,12 +233,15 @@ protected
|
|
231
233
|
#----------------------------------------------------------
|
232
234
|
# Helpers
|
233
235
|
|
236
|
+
def skip_line?
|
237
|
+
@excluding_calls_made_within_unintersting_call or calling_method_in_an_uninteresting_class?(@klass.to_s) or too_deep?
|
238
|
+
end
|
234
239
|
def too_deep?
|
235
240
|
# The + 1 is because if they're still at the initial depth (@depth - @initial_depth == 0), we want it treated as "depth 1" (1-based, for humans).
|
236
|
-
@
|
241
|
+
@max_depth and (@depth - @initial_depth + 1 > @max_depth)
|
237
242
|
end
|
238
243
|
def too_far?
|
239
|
-
@
|
244
|
+
@max_lines and (@lines_output > @max_lines)
|
240
245
|
end
|
241
246
|
def calling_method_in_an_uninteresting_class?(class_name)
|
242
247
|
( @exclude_classes + [/#{self.class.name}/] ).any? do |item|
|
@@ -477,7 +482,7 @@ if $0 == __FILE__
|
|
477
482
|
end
|
478
483
|
|
479
484
|
puts '-----------------------------------------------------------'
|
480
|
-
puts "Test
|
485
|
+
puts "Test max_depth 5: We shouldn't see the calls to f, g, ... because their depth > 5"
|
481
486
|
('a'..last='y').each do |method_name|
|
482
487
|
next_method_name = method_name.next unless method_name == last
|
483
488
|
eval <<-End, binding, __FILE__, __LINE__ + 1
|
@@ -486,7 +491,7 @@ if $0 == __FILE__
|
|
486
491
|
end
|
487
492
|
End
|
488
493
|
end
|
489
|
-
Unroller::trace(:
|
494
|
+
Unroller::trace(:max_depth => 5) do
|
490
495
|
a
|
491
496
|
end
|
492
497
|
|
@@ -507,7 +512,7 @@ if $0 == __FILE__
|
|
507
512
|
FileUtils.rm filename
|
508
513
|
|
509
514
|
puts '-----------------------------------------------------------'
|
510
|
-
puts 'Test @
|
515
|
+
puts 'Test @max_lines'
|
511
516
|
('a'..last='h').each do |method_name|
|
512
517
|
next_method_name = method_name.next unless method_name == last
|
513
518
|
eval <<-End, binding, __FILE__, __LINE__ + 1
|
@@ -516,7 +521,7 @@ if $0 == __FILE__
|
|
516
521
|
end
|
517
522
|
End
|
518
523
|
end
|
519
|
-
Unroller::trace(:
|
524
|
+
Unroller::trace(:max_lines => 20) do
|
520
525
|
a
|
521
526
|
end
|
522
527
|
|
@@ -560,5 +565,25 @@ if $0 == __FILE__
|
|
560
565
|
end
|
561
566
|
|
562
567
|
|
568
|
+
puts '-----------------------------------------------------------'
|
569
|
+
puts 'Test class definition'
|
570
|
+
Unroller::trace do
|
571
|
+
class NewClass
|
572
|
+
def hi
|
573
|
+
'hi'
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
|
579
|
+
puts '-----------------------------------------------------------'
|
580
|
+
puts 'Test rescuing exception'
|
581
|
+
def raise_an_error
|
582
|
+
raise 'an error'
|
583
|
+
end
|
584
|
+
Unroller::trace do
|
585
|
+
raise_an_error
|
586
|
+
end
|
587
|
+
|
563
588
|
|
564
589
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: unroller
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-04-
|
6
|
+
version: 0.0.4
|
7
|
+
date: 2007-04-17 00:00:00 -07:00
|
8
8
|
summary: A tool for generating human-readable "execution traces"
|
9
9
|
require_paths:
|
10
10
|
- lib
|