byebug 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/GUIDE.md +209 -0
  4. data/README.md +11 -2
  5. data/Rakefile +12 -0
  6. data/ext/byebug/byebug.c +50 -53
  7. data/ext/byebug/context.c +0 -24
  8. data/lib/byebug.rb +23 -7
  9. data/lib/byebug/command.rb +35 -24
  10. data/lib/byebug/commands/breakpoints.rb +24 -35
  11. data/lib/byebug/commands/catchpoint.rb +13 -17
  12. data/lib/byebug/commands/condition.rb +14 -19
  13. data/lib/byebug/commands/continue.rb +5 -7
  14. data/lib/byebug/commands/display.rb +3 -3
  15. data/lib/byebug/commands/edit.rb +1 -1
  16. data/lib/byebug/commands/enable.rb +18 -45
  17. data/lib/byebug/commands/eval.rb +1 -1
  18. data/lib/byebug/commands/finish.rb +1 -1
  19. data/lib/byebug/commands/frame.rb +24 -22
  20. data/lib/byebug/commands/info.rb +91 -122
  21. data/lib/byebug/commands/jump.rb +3 -8
  22. data/lib/byebug/commands/list.rb +2 -2
  23. data/lib/byebug/commands/method.rb +6 -8
  24. data/lib/byebug/commands/save.rb +1 -1
  25. data/lib/byebug/commands/set.rb +0 -12
  26. data/lib/byebug/commands/show.rb +9 -21
  27. data/lib/byebug/commands/variables.rb +3 -3
  28. data/lib/byebug/context.rb +13 -2
  29. data/lib/byebug/interface.rb +13 -7
  30. data/lib/byebug/processor.rb +23 -25
  31. data/lib/byebug/version.rb +1 -1
  32. data/old_doc/primes.rb +1 -4
  33. data/test/continue_test.rb +2 -9
  34. data/test/examples/list.rb +1 -1
  35. data/test/examples/trace.rb +1 -0
  36. data/test/help_test.rb +1 -1
  37. data/test/info_test.rb +3 -3
  38. data/test/list_test.rb +7 -1
  39. data/test/method_test.rb +0 -1
  40. data/test/show_test.rb +8 -0
  41. data/test/support/matchers.rb +4 -2
  42. data/test/trace_test.rb +18 -1
  43. metadata +2 -2
@@ -18,14 +18,9 @@ module Byebug
18
18
  end
19
19
 
20
20
  def execute
21
- if !@match[1]
22
- errmsg "\"jump\" must be followed by a line number\n"
23
- return
24
- end
25
- if !numeric?(@match[1])
26
- errmsg "Bad line number: " + @match[1]
27
- return
28
- end
21
+ return errmsg "\"jump\" must be followed by a line number\n" unless @match[1]
22
+ return errmsg "Bad line number: " + @match[1] unless numeric?(@match[1])
23
+
29
24
  line = @match[1].to_i
30
25
  line = @state.context.frame_line(0) + line if @match[1][0] == '+' or @match[1][0] == '-'
31
26
  if line == @state.context.frame_line(0)
@@ -21,7 +21,7 @@ module Byebug
21
21
  Byebug.source_reload if Command.settings[:autoreload]
22
22
  lines = LineCache::getlines @state.file, Command.settings[:autoreload]
23
23
  if !lines
24
- errmsg "No sourcefile available for #{@state.file}\n"
24
+ errmsg "No sourcefile available for #{@state.file}\n" if @state.file != '(irb)'
25
25
  return @state.previous_line
26
26
  end
27
27
 
@@ -37,7 +37,7 @@ module Byebug
37
37
  %w(list)
38
38
  end
39
39
 
40
- def help(cmd)
40
+ def description
41
41
  %{
42
42
  l[ist]\t\tlist forward
43
43
  l[ist] -\tlist backward
@@ -51,19 +51,17 @@ module Byebug
51
51
  if @match[1] == "iv"
52
52
  obj = debug_eval(@match.post_match)
53
53
  obj.instance_variables.sort.each do |v|
54
- print "%s = %s\n", v, obj.instance_variable_get(v).inspect
54
+ print "#{v} = #{obj.instance_variable_get(v).inspect}\n"
55
55
  end
56
56
  elsif @match[1]
57
57
  obj = debug_eval(@match.post_match)
58
- print "%s\n", columnize(obj.methods.sort(), Command.settings[:width])
58
+ print "#{columnize(obj.methods.sort(), Command.settings[:width])}\n"
59
59
  else
60
60
  obj = debug_eval(@match.post_match)
61
- unless obj.kind_of? Module
62
- print "Should be Class/Module: %s\n", @match.post_match
63
- else
64
- print "%s\n", columnize(obj.instance_methods(false).sort(),
65
- Command.settings[:width])
66
- end
61
+ return print "Should be Class/Module: #{@match.post_match}\n" unless
62
+ obj.kind_of? Module
63
+ print "#{columnize(obj.instance_methods(false).sort(),
64
+ Command.settings[:width])}\n"
67
65
  end
68
66
  end
69
67
 
@@ -55,7 +55,7 @@ module Byebug
55
55
  end
56
56
 
57
57
  def execute
58
- if not @match[1] or @match[1].strip.empty?
58
+ if not @match[1]
59
59
  file = open_save()
60
60
  else
61
61
  file = open(@match[1], 'w')
@@ -167,18 +167,6 @@ module Byebug
167
167
  or 0. You can see these environment settings with the "show" command
168
168
  }
169
169
  end
170
-
171
- def help(args)
172
- if args && args[1]
173
- subcmd = SetCommand.new(nil).find(Subcommands, args[1])
174
- if subcmd
175
- return "#{subcmd.short_help}.\n#{subcmd.long_help ? subcmd.long_help : ''}"
176
- else
177
- return "Invalid \"set\" subcommand \"#{args[1]}\".\n"
178
- end
179
- end
180
- description + SetCommand.new(nil).format_subcmds(Subcommands)
181
- end
182
170
  end
183
171
 
184
172
  end
@@ -198,29 +198,16 @@ module Byebug
198
198
  end
199
199
 
200
200
  def execute
201
- if not @match[1]
202
- print format_subcmds(Subcommands)
203
- else
204
- args = @match[1].split(/[ \t]+/)
205
- param = args.shift
206
- subcmd = find(Subcommands, param)
207
- if subcmd
208
- print "%s\n" % show_setting(subcmd.name)
209
- else
210
- print "Unknown show command #{param}\n"
211
- end
212
- end
213
- end
201
+ return print ShowCommand.help(nil) unless @match[1]
214
202
 
215
- def help(args)
216
- if args[1]
217
- subcmd = find(Subcommands, args[1])
218
- return "Invalid \"show\" subcommand \"#{args[1]}\"." unless subcmd
219
- str = subcmd.short_help + '.'
220
- str += "\n" + subcmd.long_help if subcmd.long_help
221
- return str
203
+ args = @match[1].split(/[ \t]+/)
204
+ param = args.shift
205
+ subcmd = find(Subcommands, param)
206
+ if subcmd
207
+ print "%s\n" % show_setting(subcmd.name)
208
+ else
209
+ print "Unknown show command #{param}\n"
222
210
  end
223
- ShowCommad.description + format_subcmds(Subcommands)
224
211
  end
225
212
 
226
213
  class << self
@@ -234,5 +221,6 @@ module Byebug
234
221
  }
235
222
  end
236
223
  end
224
+
237
225
  end
238
226
  end
@@ -14,7 +14,7 @@ module Byebug
14
14
  end
15
15
  end
16
16
  pad_with_dots(s)
17
- print "%s = %s\n", v, s
17
+ print "#{v} = #{s}\n"
18
18
  end
19
19
  end
20
20
  def var_class_self
@@ -69,7 +69,7 @@ module Byebug
69
69
  print " %s => %p\n", c, value
70
70
  end
71
71
  else
72
- print "Should be Class/Module: %s\n", @match.post_match
72
+ print "Should be Class/Module: #{@match.post_match}\n"
73
73
  end
74
74
  end
75
75
 
@@ -138,8 +138,8 @@ module Byebug
138
138
  end
139
139
 
140
140
  def execute
141
- locals = @state.context.frame_locals(@state.frame_pos)
142
141
  _self = @state.context.frame_self(@state.frame_pos)
142
+ locals = @state.context.frame_locals
143
143
  locals.keys.sort.each do |name|
144
144
  print " %s => %p\n", name, locals[name]
145
145
  end
@@ -8,8 +8,8 @@ module Byebug
8
8
  end
9
9
 
10
10
  class Context
11
- def frame_args(frame_no=0)
12
- bind = frame_binding(frame_no)
11
+ def frame_args frame_no = 0
12
+ bind = frame_binding frame_no
13
13
  return [] unless eval "__method__", bind
14
14
  begin
15
15
  eval "self.method(__method__).parameters.map{|(attr, mid)| mid}", bind
@@ -20,6 +20,17 @@ module Byebug
20
20
  end
21
21
  end
22
22
 
23
+ def frame_locals frame_no = 0
24
+ bind = frame_binding frame_no
25
+ eval "local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}", bind
26
+ end
27
+
28
+ def frame_args_info
29
+ bind = frame_binding frame_no
30
+ return [] unless eval "__method__", bind
31
+ eval "self.method(__method__).parameters", bind
32
+ end
33
+
23
34
  def handler
24
35
  Byebug.handler or raise 'No interface loaded'
25
36
  end
@@ -8,7 +8,7 @@ module Byebug
8
8
  end
9
9
 
10
10
  # Common routine for reporting byebug error messages.
11
- # Derived classed may want to override this to capture output.
11
+ # Derived classes may want to override this to capture output.
12
12
  def errmsg(*args)
13
13
  if Byebug.annotate.to_i > 2
14
14
  aprint 'error-begin'
@@ -28,6 +28,17 @@ module Byebug
28
28
  def aprint(msg)
29
29
  print afmt(msg)
30
30
  end
31
+
32
+ protected
33
+ def format(*args)
34
+ if args.is_a?(Array)
35
+ new_args = args.first
36
+ new_args = new_args % args[1..-1] unless args[1..-1].empty?
37
+ else
38
+ new_args = args
39
+ end
40
+ new_args.gsub('%', '%%')
41
+ end
31
42
  end
32
43
 
33
44
  class LocalInterface < Interface
@@ -60,13 +71,8 @@ module Byebug
60
71
  readline(prompt, false)
61
72
  end
62
73
 
63
- # Callers of this routine should make sure to use comma to separate format
64
- # argments rather than %. Otherwise it seems that if the string you want to
65
- # print has format specifier, which could happen if you are trying to show
66
- # say a source-code line with "puts" or "print" in it, this print routine
67
- # will give an error saying it is looking for more arguments.
68
74
  def print(*args)
69
- STDOUT.printf(*args)
75
+ STDOUT.printf(format(*args))
70
76
  end
71
77
 
72
78
  def close
@@ -25,26 +25,20 @@ module Byebug
25
25
  class CommandProcessor < Processor
26
26
  attr_reader :display
27
27
 
28
- # FIXME: get from Command regexp method.
29
- @@Show_breakpoints_postcmd = [
30
- /^\s*b(?:reak)?/,
31
- /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix,
32
- /^\s*del(?:ete)?(?:\s+(.*))?$/ix,
33
- /^\s* dis(?:able)? (?:\s+(.*))?$/ix,
34
- /^\s* en(?:able)? (?:\s+(.*))?$/ix
35
- # "tbreak", "clear",
28
+ @@Show_breakpoints_postcmd = [ Byebug::BreakCommand.new(nil).regexp,
29
+ Byebug::ConditionCommand.new(nil).regexp,
30
+ Byebug::DeleteCommand.new(nil).regexp,
31
+ Byebug::DisableCommand.new(nil).regexp,
32
+ Byebug::EnableCommand.new(nil).regexp
36
33
  ]
37
- @@Show_annotations_run = [
38
- /^\s*c(?:ont(?:inue)?)?(?:\s+(.*))?$/,
39
- /^\s*fin(?:ish)?$/,
40
- /^\s*n(?:ext)?([+-])?(?:\s+(.*))?$/,
41
- /^\s*s(?:tep)?([+-])?(?:\s+(.*))?$/
42
- ]
43
-
44
- @@Show_annotations_postcmd = [
45
- /^\s* down (?:\s+(.*))? .*$/x,
46
- /^\s* f(?:rame)? (?:\s+ (.*))? \s*$/x,
47
- /^\s* u(?:p)? (?:\s+(.*))?$/x
34
+ @@Show_annotations_run = [ Byebug::ContinueCommand.new(nil).regexp,
35
+ Byebug::FinishCommand.new(nil).regexp,
36
+ Byebug::NextCommand.new(nil).regexp,
37
+ Byebug::StepCommand.new(nil).regexp
38
+ ]
39
+ @@Show_annotations_postcmd = [ Byebug::DownCommand.new(nil).regexp,
40
+ Byebug::FrameCommand.new(nil).regexp,
41
+ Byebug::UpCommand.new(nil).regexp
48
42
  ]
49
43
 
50
44
  def initialize(interface = LocalInterface.new)
@@ -86,8 +80,12 @@ module Byebug
86
80
  end
87
81
 
88
82
  def self.print_location_and_text(file, line)
89
- file_line = "#{canonic_file(file)} @ #{line}\n" \
90
- "#{Byebug.line_at(file, line)}\n"
83
+ if file == '(irb)'
84
+ file_line = "#{canonic_file(file)} @ #{line}\n"
85
+ else
86
+ file_line = "#{canonic_file(file)} @ #{line}\n" \
87
+ "#{Byebug.line_at(file, line)}\n"
88
+ end
91
89
 
92
90
  # FIXME: use annotations routines
93
91
  if Byebug.annotate.to_i > 2
@@ -123,7 +121,7 @@ module Byebug
123
121
  if Byebug.annotate.to_i > 2
124
122
  print afmt("source #{file}:#{line}")
125
123
  end
126
- print "Stopped by breakpoint %d at %s:%s\n", n, file, line
124
+ print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
127
125
  end
128
126
  protect :at_breakpoint
129
127
 
@@ -146,12 +144,12 @@ module Byebug
146
144
  # Don't trace ourselves
147
145
  return if defined?(Byebug::BYEBUG_SCRIPT) && Byebug::BYEBUG_SCRIPT == file
148
146
 
149
- file = CommandProcessor.canonic_file(file)
150
147
  tracing_plus = Command.settings[:tracing_plus]
151
148
  if file != @last_file || line != @last_line || tracing_plus == false
152
149
  @last_file = file
153
150
  @last_line = line
154
- print "Tracing: #{file}:#{line} #{Byebug.line_at(file, line)}\n"
151
+ print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
152
+ "#{Byebug.line_at(file,line)}\n"
155
153
  end
156
154
  always_run(context, file, line, 2)
157
155
  end
@@ -232,7 +230,7 @@ module Byebug
232
230
 
233
231
  preloop(commands, context)
234
232
 
235
- if Command.settings[:autolist] == 0
233
+ if Command.settings[:autolist] == 0 || file == '(irb)'
236
234
  CommandProcessor.print_location_and_text(file, line)
237
235
  end
238
236
 
@@ -1,3 +1,3 @@
1
1
  module Byebug
2
- VERSION = '1.3.0'
2
+ VERSION = '1.3.1'
3
3
  end
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env ruby
2
1
  # Enumerator for primes
3
2
  class SievePrime
4
3
  @@odd_primes = []
@@ -14,7 +13,7 @@ class SievePrime
14
13
  end
15
14
  unless not_prime
16
15
  @@odd_primes << candidate
17
- yield candidate
16
+ yield candidate
18
17
  end
19
18
  candidate += 2
20
19
  end
@@ -24,5 +23,3 @@ SievePrime.next_prime do |prime|
24
23
  puts prime
25
24
  break if prime > 10
26
25
  end
27
-
28
-
@@ -17,12 +17,6 @@ class TestContinue < TestDsl::TestCase
17
17
  enter 'cont 4'
18
18
  debug_file('continue') { state.line.must_equal 4 }
19
19
  end
20
-
21
- it "must not keep temporal breakpoint when line specified" do
22
- skip 'Not working yet, breakpoint is currently kept'
23
- enter 'cont 4'
24
- debug_file('continue') { Byebug.breakpoints.size.must_equal 0 }
25
- end
26
20
  end
27
21
 
28
22
  describe "unsuccessful" do
@@ -34,9 +28,8 @@ class TestContinue < TestDsl::TestCase
34
28
  it "must show error if specified line is not valid" do
35
29
  enter 'cont 123'
36
30
  debug_file('continue')
37
- check_output_includes "Line 123 is not a stopping point in file \"#{fullpath('continue')}\".", interface.error_queue
31
+ check_output_includes "Line 123 is not a stopping point in file " \
32
+ "\"#{fullpath('continue')}\"", interface.error_queue
38
33
  end
39
-
40
- it "must ignore the line if the context is dead"
41
34
  end
42
35
  end
@@ -20,4 +20,4 @@ byebug
20
20
  20
21
21
  21
22
22
  22
23
- 23
23
+ a = '%23'
@@ -5,3 +5,4 @@ $bla = 4
5
5
  $bla = 5
6
6
  $bla = 6
7
7
  $bla = 7
8
+ $bla = (0 == (7 % $bla))
@@ -35,7 +35,7 @@ class TestHelp < TestDsl::TestCase
35
35
  it 'must show a command\'s help' do
36
36
  enter 'help break'
37
37
  debug_file 'help'
38
- check_output_includes Byebug::AddBreakpoint.help(nil)
38
+ check_output_includes Byebug::BreakCommand.help(nil)
39
39
  end
40
40
 
41
41
  describe 'Post Mortem' do
@@ -55,7 +55,7 @@ class TestInfo < TestDsl::TestCase
55
55
  it 'must show all display expressions' do
56
56
  enter 'display 3 + 3', 'display a + b', 'info display'
57
57
  debug_file 'info'
58
- check_output_includes 'Auto-display expressions now in effect:',
58
+ check_output_includes "Auto-display expressions now in effect:\n" \
59
59
  'Num Enb Expression',
60
60
  '1: y 3 + 3',
61
61
  '2: y a + b'
@@ -273,10 +273,10 @@ class TestInfo < TestDsl::TestCase
273
273
  '@foo = "bar"'
274
274
  end
275
275
 
276
- it 'must handle printf strings correctly' do
276
+ it 'must correctly print variables containing % sign' do
277
277
  enter 'break 32', 'cont', 'info variables'
278
278
  debug_file 'info'
279
- check_output_includes 'e = "%%.2f"'
279
+ check_output_includes 'e = "%.2f"'
280
280
  end
281
281
  end
282
282
 
@@ -56,7 +56,7 @@ class TestList < TestDsl::TestCase
56
56
  end
57
57
  end
58
58
 
59
- describe 'list backward' do
59
+ describe 'list backwards' do
60
60
  temporary_change_hash Byebug::Command.settings, :autolist, 0
61
61
 
62
62
  it 'must show surrounding lines with the first call' do
@@ -165,6 +165,12 @@ class TestList < TestDsl::TestCase
165
165
  interface.error_queue
166
166
  end
167
167
 
168
+ it 'must correctly print lines containing % sign' do
169
+ enter 'list 23'
170
+ debug_file 'list'
171
+ check_output_includes "23: a = '%23'"
172
+ end
173
+
168
174
  describe 'Post Mortem' do
169
175
  it 'must work in post-mortem mode' do
170
176
  enter 'cont'
@@ -1,7 +1,6 @@
1
1
  require_relative 'test_helper'
2
2
 
3
3
  class TestMethod < TestDsl::TestCase
4
-
5
4
  temporary_change_hash Byebug::Command.settings, :autolist, 0
6
5
 
7
6
  describe 'show instance method of a class' do