unroller 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/unroller.rb +123 -44
  2. metadata +2 -12
@@ -22,6 +22,7 @@ require 'quality_extensions/module/malias_method_chain'
22
22
  require 'quality_extensions/module/attribute_accessors'
23
23
  require 'quality_extensions/enumerable/select_until'
24
24
  require 'quality_extensions/module/bool_attr_accessor'
25
+ require 'quality_extensions/object/pp_s'
25
26
  gem 'colored'
26
27
  require 'colored'
27
28
  #gem 'extensions'
@@ -30,10 +31,8 @@ require 'colored'
30
31
  require 'English'
31
32
  require 'pp'
32
33
  require 'stringio'
33
- gem 'termios'
34
- require 'termios'
35
- gem 'colored'
36
34
 
35
+ gem 'colored'
37
36
  # To disable color, uncomment this:
38
37
  #class String
39
38
  # def colorize(string, options = {})
@@ -42,12 +41,55 @@ gem 'colored'
42
41
  #end
43
42
 
44
43
  begin
45
- # Set up termios so that it returns immediately when you press a key.
46
- # (http://blog.rezra.com/articles/2005/12/05/single-character-input)
47
- t = Termios.tcgetattr(STDIN)
48
- save_terminal_attributes = t.dup
49
- t.lflag &= ~Termios::ICANON
50
- Termios.tcsetattr(STDIN, 0, t)
44
+ gem 'termios'
45
+ require 'termios'
46
+ begin
47
+ # Set up termios so that it returns immediately when you press a key.
48
+ # (http://blog.rezra.com/articles/2005/12/05/single-character-input)
49
+ t = Termios.tcgetattr(STDIN)
50
+ save_terminal_attributes = t.dup
51
+ t.lflag &= ~Termios::ICANON
52
+ Termios.tcsetattr(STDIN, 0, t)
53
+
54
+ # Set terminal_attributes back to how we found them...
55
+ at_exit { Termios.tcsetattr(STDIN, 0, save_terminal_attributes) }
56
+ rescue RuntimeError => exception # Necessary for automated testing.
57
+ if exception.message =~ /can't get terminal parameters/
58
+ puts 'Warning: Terminal not found.'
59
+ $interactive = false
60
+ elsif exception.message =~ /Inappropriate ioctl for device/
61
+ puts "Warning: #{exception.inspect}"
62
+ # This error happens when a Rails app is started with script/server -d
63
+ # By rescuing this error, we should be able to tail log/mongrel.log to see the output.
64
+ else
65
+ raise
66
+ end
67
+ end
68
+ $termios_loaded = true
69
+ rescue Gem::LoadError
70
+ $termios_loaded = false
71
+ end
72
+
73
+ class IO
74
+ # Gets a single character, as a string.
75
+ # Adjusts for the different behavior of getc if we are using termios to get it to return immediately when you press a single key
76
+ # or if they are not using that behavior and thus have to press Enter after their single key.
77
+ def getch
78
+ response = getc
79
+ if !$termios_loaded
80
+ next_char = getc
81
+ new_line_characters_expected = ["\n"]
82
+ #new_line_characters_expected = ["\n", "\r"] if windows?
83
+ if next_char.chr.in?(new_line_characters_expected)
84
+ # Eat the newline character
85
+ else
86
+ # Don't eat it
87
+ # (This case is necessary, for escape sequences, for example, where they press only one key, but it produces multiple characters.)
88
+ $stdin.ungetc(next_char)
89
+ end
90
+ end
91
+ response.chr
92
+ end
51
93
  end
52
94
 
53
95
  class String
@@ -86,10 +128,11 @@ class Unroller
86
128
  end
87
129
  def to_s
88
130
  #@variables.inspect
89
- @variables.map do |variable|
131
+ ret = @variables.map do |variable|
90
132
  name, value = *variable
91
133
  "#{name} = #{value.inspect}"
92
134
  end.join('; ').bracket(' (', ')')
135
+ ret[0..70] + '...' # Maybe truncating it could be optional in the future, but for now it's just too cluttered
93
136
  end
94
137
  def verbose_to_s
95
138
  @variables.map do |variable|
@@ -103,6 +146,7 @@ class Unroller
103
146
  end
104
147
  end
105
148
  @@instance = nil
149
+ @@quiting = false
106
150
 
107
151
  Call = Struct.new(:file, :line_num, :klass, :name, :full_name)
108
152
  # AKA stack frame?
@@ -186,6 +230,7 @@ class Unroller
186
230
 
187
231
  # "Presets"
188
232
  # Experimental -- subject to change a lot before it's finalized
233
+ options[:presets] = options.delete(:only) if options.has_key?(:only)
189
234
  options[:presets] = options.delete(:debugging) if options.has_key?(:debugging)
190
235
  options[:presets] = options.delete(:preset) if options.has_key?(:preset)
191
236
  options[:presets] = [options[:presets]] unless options[:presets].is_a?(Array)
@@ -310,8 +355,11 @@ class Unroller
310
355
  end
311
356
 
312
357
  def trace(&block)
358
+ catch :quit do
359
+ throw :quit if @@quiting
313
360
  if @tracing
314
361
  yield if block_given?
362
+ # No need to call set_trace_func again; we're already tracing
315
363
  return
316
364
  end
317
365
 
@@ -321,7 +369,13 @@ class Unroller
321
369
 
322
370
  if @condition.call
323
371
 
324
- trap_chain("INT") { set_trace_func(nil) }
372
+ trap_chain("INT") do
373
+ puts
374
+ puts 'Exiting trace...'
375
+ set_trace_func(nil)
376
+ @@quiting = true
377
+ throw :quit
378
+ end
325
379
 
326
380
 
327
381
 
@@ -333,6 +387,7 @@ class Unroller
333
387
 
334
388
  # (This is the meat of the library right here, so let's set it off with at least 5 blank lines.)
335
389
  set_trace_func( proc do |event, file, line, id, binding, klass|
390
+ return if @@quiting
336
391
  begin # begin/rescue block
337
392
  @event, @file, @line, @id, @binding, @klass =
338
393
  event, file, line, id, binding, klass
@@ -428,15 +483,31 @@ class Unroller
428
483
  if @interactive && !(@last_call == current_call)
429
484
  #(print '(o = Step out of | s = Skip = Step over | default = Step into > '; response = $stdin.gets) if @interactive
430
485
 
431
- while response.nil? do
486
+ while response.nil? or !response.in? ['i',' ',"\e[C","\e[19~", 'v',"\e[B","\e[20~", 'u',"\e[D", 'r', "\n", 'q'] do
432
487
  print "Debugger (" +
433
- "Step out".menu_item(:red, 'u') + ' | ' +
434
- "Step over (or Enter key)".menu_item(:cyan, 'v') + ' | ' +
435
- "Step into (Space)".menu_item(:green, 'i') + ' | ' +
488
+ "Step into (F8/Right/Space)".menu_item(:green, 'i') + ' | ' +
489
+ "Step over (F9/Down/Enter)".menu_item(:cyan, 'v') + ' | ' +
490
+ "Step out (Left)".menu_item(:red, 'u') + ' | ' +
436
491
  "show Locals".menu_item(:yellow, 'l') + ' | ' +
437
- "Run".menu_item(:blue) +
492
+ "Run".menu_item(:blue) + ' | ' +
493
+ "Quit".menu_item(:magenta) +
438
494
  ') > '
439
- response = $stdin.getc.chr.downcase
495
+ $stdout.flush
496
+
497
+ response = $stdin.getch.downcase
498
+
499
+ # Escape sequence such as the up arrow key ("\e[A")
500
+ if response == "\e"
501
+ response << (next_char = $stdin.getch)
502
+ if next_char == '['
503
+ response << (next_char = $stdin.getch)
504
+ if next_char.in? ['1', '2']
505
+ response << (next_char = $stdin.getch)
506
+ response << (next_char = $stdin.getch)
507
+ end
508
+ end
509
+ end
510
+
440
511
  puts unless response == "\n"
441
512
 
442
513
  case response
@@ -446,18 +517,24 @@ class Unroller
446
517
  end
447
518
  end
448
519
  end
520
+
449
521
  if response
450
522
  case response
451
- when 'r' # Run
452
- @interactive = false
453
- when 'u' # Step out
454
- @silent_until_return_to_this_depth = @internal_depth - 1
455
- #puts "Setting @silent_until_return_to_this_depth = #{@silent_until_return_to_this_depth}"
456
- when 'v', "\n" # Step over = Ignore anything with a greater depth.
523
+ when 'i', ' ', "\e[C", "\e[19~" # (Right, F8)
524
+ # keep right on tracing...
525
+ when 'v', "\n", "\e[B", "\e[20~" # (Down, F9) Step over = Ignore anything with a greater depth.
457
526
  @only_makes_sense_if_next_event_is_call = true
458
527
  @silent_until_return_to_this_depth = @internal_depth
528
+ when 'u', "\e[D" # (Left) Step out
529
+ @silent_until_return_to_this_depth = @internal_depth - 1
530
+ #puts "Setting @silent_until_return_to_this_depth = #{@silent_until_return_to_this_depth}"
531
+ when 'r' # Run
532
+ @interactive = false
533
+ when 'q'
534
+ @@quiting = true
535
+ throw :quit
459
536
  else
460
- # 'i', ' ', or any other key will simply do the default, which is to keep right on tracing...
537
+ # we shouldn't get here
461
538
  end
462
539
  end
463
540
 
@@ -635,7 +712,9 @@ class Unroller
635
712
  ensure
636
713
  trace_off if block_given?
637
714
  end # rescue/ensure block
715
+ end
638
716
  end # def trace(&block)
717
+
639
718
  class << self
640
719
  alias_method :trace_on, :trace
641
720
  end
@@ -1068,13 +1147,13 @@ if $0 == __FILE__
1068
1147
  ('a'..last='y').each do |method_name|
1069
1148
  next_method_name = method_name.next unless method_name == last
1070
1149
  eval <<-End, binding, __FILE__, __LINE__ + 1
1071
- def #{method_name}
1072
- #{next_method_name}
1150
+ def _#{method_name}
1151
+ #{next_method_name && "_#{next_method_name}"}
1073
1152
  end
1074
1153
  End
1075
1154
  end
1076
1155
  Unroller::trace(:depth => 5) do
1077
- a
1156
+ _a
1078
1157
  end
1079
1158
 
1080
1159
  herald '-----------------------------------------------------------'
@@ -1082,13 +1161,13 @@ if $0 == __FILE__
1082
1161
  ('a'..last='y').each do |method_name|
1083
1162
  next_method_name = method_name.next unless method_name == last
1084
1163
  eval <<-End, binding, __FILE__, __LINE__ + 1
1085
- def #{method_name}
1086
- #{next_method_name}
1164
+ def _#{method_name}
1165
+ #{next_method_name && "_#{next_method_name}"}
1087
1166
  #{'Unroller::trace(:depth => caller(0).size)' if method_name == last }
1088
1167
  end
1089
1168
  End
1090
1169
  end
1091
- a
1170
+ _a
1092
1171
  Unroller::trace_off
1093
1172
 
1094
1173
 
@@ -1117,14 +1196,14 @@ if $0 == __FILE__
1117
1196
  ('a'..last='c').each do |method_name|
1118
1197
  next_method_name = method_name.next unless method_name == last
1119
1198
  eval <<-End, binding, __FILE__, __LINE__ + 1
1120
- def #{method_name}
1121
- #{next_method_name}
1199
+ def _#{method_name}
1200
+ #{next_method_name && "_#{next_method_name}"}
1122
1201
  end
1123
1202
  End
1124
1203
  end
1125
1204
  go_to_depth_and_call_1(14) do
1126
1205
  Unroller::trace(:depth => :use_call_stack_depth) do
1127
- a
1206
+ _a
1128
1207
  end
1129
1208
  end
1130
1209
 
@@ -1132,7 +1211,7 @@ if $0 == __FILE__
1132
1211
  herald 'Testing without :depth => :use_call_stack_depth (for comparison)'
1133
1212
  go_to_depth_and_call_1(14) do
1134
1213
  Unroller::trace() do
1135
- a
1214
+ _a
1136
1215
  end
1137
1216
  end
1138
1217
 
@@ -1141,13 +1220,13 @@ if $0 == __FILE__
1141
1220
  ('a'..last='y').each do |method_name|
1142
1221
  next_method_name = method_name.next unless method_name == last
1143
1222
  eval <<-End, binding, __FILE__, __LINE__ + 1
1144
- def #{method_name}
1145
- #{next_method_name}
1223
+ def _#{method_name}
1224
+ #{next_method_name && "_#{next_method_name}"}
1146
1225
  end
1147
1226
  End
1148
1227
  end
1149
1228
  Unroller::trace(:max_depth => 5) do
1150
- a
1229
+ _a
1151
1230
  end
1152
1231
 
1153
1232
  herald '-----------------------------------------------------------'
@@ -1171,13 +1250,13 @@ if $0 == __FILE__
1171
1250
  ('a'..last='h').each do |method_name|
1172
1251
  next_method_name = method_name.next unless method_name == last
1173
1252
  eval <<-End, binding, __FILE__, __LINE__ + 1
1174
- def #{method_name}
1175
- #{next_method_name}
1253
+ def _#{method_name}
1254
+ #{next_method_name && "_#{next_method_name}"}
1176
1255
  end
1177
1256
  End
1178
1257
  end
1179
1258
  Unroller::trace(:max_lines => 20) do
1180
- a
1259
+ _a
1181
1260
  end
1182
1261
 
1183
1262
  herald '-----------------------------------------------------------'
@@ -1275,8 +1354,8 @@ if $0 == __FILE__
1275
1354
  ('a'..last='h').each do |method_name|
1276
1355
  next_method_name = method_name.next unless method_name == last
1277
1356
  eval <<-End, binding, __FILE__, __LINE__ + 1
1278
- def #{method_name}
1279
- #{next_method_name}
1357
+ def _#{method_name}
1358
+ #{next_method_name && "_#{next_method_name}"}
1280
1359
  #{'Interesting::method' if method_name == last }
1281
1360
  #{'Interesting.new.method' if method_name == last }
1282
1361
  end
@@ -1285,7 +1364,7 @@ if $0 == __FILE__
1285
1364
  end
1286
1365
  end
1287
1366
  def create_an_instance_of_UninterestingClassThatCluttersUpOnesTraces
1288
- Uninteresting::ClassThatCluttersUpOnesTraces.new.a
1367
+ Uninteresting::ClassThatCluttersUpOnesTraces.new._a
1289
1368
  end
1290
1369
  Unroller::trace(:exclude_classes => Uninteresting::ClassThatCluttersUpOnesTraces) do
1291
1370
  create_an_instance_of_UninterestingClassThatCluttersUpOnesTraces
@@ -1496,7 +1575,7 @@ if $0 == __FILE__
1496
1575
  def block_taker(&block)
1497
1576
  puts "I'm the block taker. I take blocks."
1498
1577
  puts "Please Step Over the next line."
1499
- yield # buggy!
1578
+ yield # buggy! it keeps stopping at every line in the yielded block, but shouldn't.
1500
1579
  # false:: (unroller.rb:1433) (line): ??
1501
1580
  puts "Done yielding to the block"
1502
1581
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unroller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Rick
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-21 00:00:00 -08:00
12
+ date: 2008-12-30 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,16 +42,6 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: "0"
44
44
  version:
45
- - !ruby/object:Gem::Dependency
46
- name: termios
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: "0"
54
- version:
55
45
  description: A debugging/tracing tool for Ruby. While it is enabled, it will watch every Ruby statement and method call that gets executed and will display the source code that is being executed in real time on your screen.
56
46
  email:
57
47
  executables: []