byebug 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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