byebug 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +125 -99
  4. data/CONTRIBUTING.md +4 -6
  5. data/GUIDE.md +42 -20
  6. data/Gemfile +5 -3
  7. data/README.md +2 -3
  8. data/Rakefile +11 -7
  9. data/bin/byebug +2 -252
  10. data/byebug.gemspec +7 -4
  11. data/ext/byebug/byebug.c +17 -18
  12. data/ext/byebug/byebug.h +4 -5
  13. data/ext/byebug/context.c +37 -39
  14. data/ext/byebug/threads.c +39 -18
  15. data/lib/byebug.rb +2 -110
  16. data/lib/byebug/attacher.rb +23 -0
  17. data/lib/byebug/breakpoint.rb +60 -0
  18. data/lib/byebug/command.rb +62 -70
  19. data/lib/byebug/commands/break.rb +24 -24
  20. data/lib/byebug/commands/catchpoint.rb +18 -10
  21. data/lib/byebug/commands/condition.rb +18 -17
  22. data/lib/byebug/commands/continue.rb +17 -9
  23. data/lib/byebug/commands/delete.rb +19 -13
  24. data/lib/byebug/commands/display.rb +19 -53
  25. data/lib/byebug/commands/edit.rb +7 -4
  26. data/lib/byebug/commands/enable_disable.rb +130 -0
  27. data/lib/byebug/commands/eval.rb +40 -22
  28. data/lib/byebug/commands/finish.rb +13 -4
  29. data/lib/byebug/commands/frame.rb +65 -45
  30. data/lib/byebug/commands/help.rb +17 -18
  31. data/lib/byebug/commands/history.rb +14 -8
  32. data/lib/byebug/commands/info.rb +160 -182
  33. data/lib/byebug/commands/interrupt.rb +4 -1
  34. data/lib/byebug/commands/irb.rb +30 -0
  35. data/lib/byebug/commands/kill.rb +7 -8
  36. data/lib/byebug/commands/list.rb +71 -66
  37. data/lib/byebug/commands/method.rb +14 -6
  38. data/lib/byebug/commands/pry.rb +35 -0
  39. data/lib/byebug/commands/quit.rb +9 -6
  40. data/lib/byebug/commands/reload.rb +5 -2
  41. data/lib/byebug/commands/restart.rb +13 -9
  42. data/lib/byebug/commands/save.rb +17 -17
  43. data/lib/byebug/commands/set.rb +16 -15
  44. data/lib/byebug/commands/show.rb +10 -11
  45. data/lib/byebug/commands/source.rb +11 -5
  46. data/lib/byebug/commands/stepping.rb +38 -24
  47. data/lib/byebug/commands/threads.rb +45 -31
  48. data/lib/byebug/commands/trace.rb +22 -9
  49. data/lib/byebug/commands/undisplay.rb +45 -0
  50. data/lib/byebug/commands/variables.rb +83 -27
  51. data/lib/byebug/context.rb +25 -22
  52. data/lib/byebug/core.rb +82 -0
  53. data/lib/byebug/helper.rb +37 -28
  54. data/lib/byebug/history.rb +8 -4
  55. data/lib/byebug/interface.rb +12 -17
  56. data/lib/byebug/interfaces/local_interface.rb +11 -8
  57. data/lib/byebug/interfaces/remote_interface.rb +11 -8
  58. data/lib/byebug/interfaces/script_interface.rb +9 -6
  59. data/lib/byebug/options.rb +46 -0
  60. data/lib/byebug/processor.rb +7 -1
  61. data/lib/byebug/processors/command_processor.rb +135 -125
  62. data/lib/byebug/processors/control_command_processor.rb +23 -23
  63. data/lib/byebug/remote.rb +17 -26
  64. data/lib/byebug/runner.rb +100 -0
  65. data/lib/byebug/setting.rb +33 -8
  66. data/lib/byebug/settings/autoeval.rb +5 -15
  67. data/lib/byebug/settings/autoirb.rb +4 -1
  68. data/lib/byebug/settings/autolist.rb +5 -2
  69. data/lib/byebug/settings/autoreload.rb +5 -2
  70. data/lib/byebug/settings/autosave.rb +6 -2
  71. data/lib/byebug/settings/basename.rb +7 -2
  72. data/lib/byebug/settings/callstyle.rb +4 -1
  73. data/lib/byebug/settings/forcestep.rb +6 -3
  74. data/lib/byebug/settings/fullpath.rb +5 -2
  75. data/lib/byebug/settings/histfile.rb +5 -3
  76. data/lib/byebug/settings/histsize.rb +5 -3
  77. data/lib/byebug/settings/linetrace.rb +4 -1
  78. data/lib/byebug/settings/listsize.rb +5 -1
  79. data/lib/byebug/settings/post_mortem.rb +21 -13
  80. data/lib/byebug/settings/stack_on_error.rb +6 -2
  81. data/lib/byebug/settings/testing.rb +6 -1
  82. data/lib/byebug/settings/tracing_plus.rb +5 -1
  83. data/lib/byebug/settings/verbose.rb +13 -2
  84. data/lib/byebug/settings/width.rb +4 -1
  85. data/lib/byebug/version.rb +1 -1
  86. data/test/{break_test.rb → commands/break_test.rb} +41 -53
  87. data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
  88. data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
  89. data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
  90. data/test/commands/display_test.rb +37 -0
  91. data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
  92. data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
  93. data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
  94. data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
  95. data/test/{help_test.rb → commands/help_test.rb} +21 -4
  96. data/test/{history_test.rb → commands/history_test.rb} +0 -0
  97. data/test/{info_test.rb → commands/info_test.rb} +5 -55
  98. data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
  99. data/test/commands/irb_test.rb +28 -0
  100. data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
  101. data/test/{list_test.rb → commands/list_test.rb} +1 -1
  102. data/test/{method_test.rb → commands/method_test.rb} +0 -0
  103. data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
  104. data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
  105. data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
  106. data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
  107. data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
  108. data/test/{save_test.rb → commands/save_test.rb} +2 -2
  109. data/test/{set_test.rb → commands/set_test.rb} +9 -2
  110. data/test/{show_test.rb → commands/show_test.rb} +1 -1
  111. data/test/{source_test.rb → commands/source_test.rb} +3 -3
  112. data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
  113. data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
  114. data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
  115. data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
  116. data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
  117. data/test/debugger_alias_test.rb +2 -2
  118. data/test/runner_test.rb +127 -0
  119. data/test/support/matchers.rb +27 -25
  120. data/test/support/test_interface.rb +9 -5
  121. data/test/support/utils.rb +96 -101
  122. data/test/test_helper.rb +32 -20
  123. metadata +93 -68
  124. data/lib/byebug/commands/enable.rb +0 -154
  125. data/lib/byebug/commands/repl.rb +0 -126
  126. data/test/irb_test.rb +0 -47
  127. data/test/support/breakpoint.rb +0 -13
@@ -3,22 +3,64 @@ require 'forwardable'
3
3
  require 'byebug/helper'
4
4
 
5
5
  module Byebug
6
+ #
7
+ # Parent class of all byebug commands.
8
+ #
9
+ # Subclasses need to implement a `regexp` and an `execute` command.
10
+ #
6
11
  class Command
7
12
  Subcmd = Struct.new(:name, :min, :help)
8
13
 
14
+ def initialize(state)
15
+ @match, @state = nil, state
16
+ end
17
+
18
+ def match(input)
19
+ @match = regexp.match(input)
20
+ end
21
+
22
+ protected
23
+
24
+ extend Forwardable
25
+ def_delegators :@state, :errmsg, :puts
26
+
27
+ def confirm(msg)
28
+ @state.confirm(msg) == 'y'
29
+ end
30
+
31
+ def bb_eval(str, b = get_binding)
32
+ eval(str, b)
33
+ rescue StandardError, ScriptError => e
34
+ at = eval('Thread.current.backtrace_locations', b)
35
+ puts "#{at.shift}: #{e.class} Exception(#{e.message})"
36
+ at.each { |path| puts "\tfrom #{path}" }
37
+ nil
38
+ end
39
+
40
+ def bb_warning_eval(str, b = get_binding)
41
+ eval(str, b)
42
+ rescue StandardError, ScriptError => e
43
+ puts "#{e.class} Exception: #{e.message}"
44
+ nil
45
+ end
46
+
47
+ def get_binding(pos = @state.frame_pos)
48
+ @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING
49
+ end
50
+
9
51
  class << self
10
- attr_accessor :allow_in_control, :unknown
52
+ attr_accessor :allow_in_control
11
53
  attr_writer :allow_in_post_mortem, :always_run
12
54
 
13
55
  def allow_in_post_mortem
14
- @allow_in_post_mortem ||= !defined?(@allow_in_post_mortem) ? true : false
56
+ !defined?(@allow_in_post_mortem) ? true : false
15
57
  end
16
58
 
17
59
  def always_run
18
60
  @always_run ||= 0
19
61
  end
20
62
 
21
- def help(args)
63
+ def help(args = nil)
22
64
  if args && args[1]
23
65
  output = format_subcmd(args[1])
24
66
  else
@@ -28,36 +70,33 @@ module Byebug
28
70
  output
29
71
  end
30
72
 
31
- def find(subcmds, param)
32
- param.downcase!
33
- for try_subcmd in subcmds do
34
- if (param.size >= try_subcmd.min) and
35
- (try_subcmd.name[0..param.size-1] == param)
36
- return try_subcmd
73
+ def find(subcmds, str)
74
+ str.downcase!
75
+ subcmds.each do |subcmd|
76
+ if (str.size >= subcmd.min) && (subcmd.name[0..str.size - 1] == str)
77
+ return subcmd
37
78
  end
38
79
  end
39
- return nil
80
+
81
+ nil
40
82
  end
41
83
 
42
84
  def format_subcmd(subcmd_name)
43
85
  subcmd = find(self::Subcommands, subcmd_name)
44
- return "Invalid \"#{names.join("|")}\" " \
86
+ return "Invalid \"#{names.join('|')}\" " \
45
87
  "subcommand \"#{args[1]}\"." unless subcmd
46
88
 
47
- return "#{subcmd.help}.\n"
89
+ "\n #{subcmd.help}.\n\n"
48
90
  end
49
91
 
50
92
  def format_subcmds
51
- cmd_name = names.join("|")
52
- s = "\n" \
53
- "--\n" \
54
- "List of \"#{cmd_name}\" subcommands:\n" \
55
- "--\n"
93
+ header = names.join('|')
94
+ s = " List of \"#{header}\" subcommands:\n --\n"
56
95
  w = self::Subcommands.map(&:name).max_by(&:size).size
57
- for subcmd in self::Subcommands do
58
- s += sprintf "%s %-#{w}s -- %s\n", cmd_name, subcmd.name, subcmd.help
96
+ self::Subcommands.each do |subcmd|
97
+ s += format(" %s %-#{w}s -- %s\n", header, subcmd.name, subcmd.help)
59
98
  end
60
- return s
99
+ s + "\n"
61
100
  end
62
101
 
63
102
  def commands
@@ -73,58 +112,11 @@ module Byebug
73
112
  require file
74
113
  end
75
114
 
76
- Byebug.constants.grep(/Functions$/).map {
77
- |name| Byebug.const_get(name)
78
- }.each { |mod| include mod }
79
- end
80
- end
81
-
82
- def initialize(state)
83
- @match, @state = nil, state
84
- end
85
-
86
- def match(input)
87
- @match = regexp.match(input)
88
- end
89
-
90
- protected
91
-
92
- extend Forwardable
93
- def_delegators :@state, :errmsg, :print
94
-
95
- def confirm(msg)
96
- @state.confirm(msg) == 'y'
97
- end
98
-
99
- def bb_eval(str, b = get_binding)
100
- begin
101
- eval(str, b)
102
- rescue StandardError, ScriptError => e
103
- at = eval('Thread.current.backtrace_locations(1)', b)
104
- print "#{at.shift}: #{e.class} Exception(#{e.message})\n"
105
- for i in at
106
- print "\tfrom #{i}\n"
107
- end
108
- nil
109
- end
110
- end
111
-
112
- def bb_warning_eval(str, b = get_binding)
113
- begin
114
- eval(str, b)
115
- rescue StandardError, ScriptError => e
116
- print "#{e.class} Exception: #{e.message}\n"
117
- nil
115
+ Byebug.constants.grep(/Functions$/).map do |name|
116
+ include Byebug.const_get(name)
118
117
  end
119
118
  end
120
-
121
- def get_binding pos = @state.frame_pos
122
- @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING
123
- end
124
-
125
- def get_context(thnum)
126
- Byebug.contexts.find {|c| c.thnum == thnum}
127
- end
119
+ end
128
120
  end
129
121
 
130
122
  Command.load_commands
@@ -1,14 +1,19 @@
1
1
  module Byebug
2
+ #
3
+ # Implements breakpoint functionality
4
+ #
2
5
  class BreakCommand < Command
3
6
  self.allow_in_post_mortem = false
4
7
  self.allow_in_control = true
5
8
 
9
+ POSITION_REGEXP = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))'
10
+
6
11
  def regexp
7
- /^\s* b(?:reak)? (?:\s+ #{Position_regexp})? (?:\s+(.+))? \s*$/x
12
+ /^\s* b(?:reak)? (?:\s+ #{POSITION_REGEXP})? (?:\s+(.+))? \s*$/x
8
13
  end
9
14
 
10
15
  def execute
11
- return print BreakCommand.help(nil) if BreakCommand.names.include?(@match[0])
16
+ return puts(self.class.help) if self.class.names.include?(@match[0])
12
17
 
13
18
  if @match[1]
14
19
  line, _, _, expr = @match.captures
@@ -17,15 +22,15 @@ module Byebug
17
22
  end
18
23
 
19
24
  if expr && file.nil? && line.nil?
20
- return errmsg "Invalid breakpoint location: #{expr}\n"
25
+ return errmsg("Invalid breakpoint location: #{expr}")
21
26
  elsif expr && expr !~ /^\s*if\s+(.+)/
22
- return errmsg "Expecting \"if\" in breakpoint condition, got: #{expr}\n"
27
+ return errmsg("Expecting \"if\" in breakpoint condition, got: #{expr}")
23
28
  else
24
29
  expr = $1
25
30
  end
26
31
 
27
32
  if file.nil? && !@state.context
28
- return errmsg "We are not in a state that has an associated file\n"
33
+ return errmsg('We are not in a state that has an associated file')
29
34
  end
30
35
 
31
36
  file = @state.file if file.nil?
@@ -33,37 +38,32 @@ module Byebug
33
38
 
34
39
  if line =~ /^\d+$/
35
40
  path = CommandProcessor.canonic_file(file)
36
- return errmsg "No file named #{path}\n" unless File.exist?(file)
41
+ return errmsg("No file named #{path}") unless File.exist?(file)
37
42
 
38
- line, n = line.to_i, File.foreach(file).count
39
- return errmsg "There are only #{n} lines in file #{path}\n" if line > n
43
+ l, n = line.to_i, File.foreach(file).count
44
+ return errmsg("There are only #{n} lines in file #{path}") if l > n
40
45
 
41
46
  autoreload = Setting[:autoreload]
42
47
  possible_lines = LineCache.trace_line_numbers(file, autoreload)
43
- if !possible_lines.member?(line)
44
- return errmsg \
45
- "Line #{line} is not a valid breakpoint in file #{path}\n"
48
+ unless possible_lines.member?(l)
49
+ return errmsg("Line #{l} is not a valid breakpoint in file #{path}")
46
50
  end
47
51
 
48
- b = Byebug.add_breakpoint file, line, expr
49
- print "Created breakpoint #{b.id} at #{path}:#{line}\n"
52
+ b = Breakpoint.add(file, l, expr)
53
+ puts "Created breakpoint #{b.id} at #{path}:#{l}"
50
54
 
51
- if !syntax_valid?(expr)
52
- errmsg "Incorrect expression \"#{expr}\"; breakpoint disabled.\n"
55
+ unless syntax_valid?(expr)
56
+ errmsg("Incorrect expression \"#{expr}\"; breakpoint disabled.")
53
57
  b.enabled = false
54
58
  end
55
59
 
56
60
  else
57
- klass = bb_warning_eval(file)
58
- if klass && klass.kind_of?(Module)
59
- class_name = klass.name
60
- else
61
- return errmsg "Unknown class #{file}\n"
62
- end
61
+ kl = bb_warning_eval(file)
62
+ return errmsg("Unknown class #{file}") unless kl && kl.is_a?(Module)
63
63
 
64
- method = line.intern
65
- b = Byebug.add_breakpoint class_name, method, expr
66
- print "Created breakpoint #{b.id} at #{class_name}::#{method}\n"
64
+ class_name, method = kl.name, line.intern
65
+ b = Breakpoint.add(class_name, method, expr)
66
+ puts "Created breakpoint #{b.id} at #{class_name}::#{method}"
67
67
  end
68
68
  end
69
69
 
@@ -1,4 +1,9 @@
1
1
  module Byebug
2
+ #
3
+ # Implements exception catching.
4
+ #
5
+ # Enables the user to catch unhandled assertion when they happen.
6
+ #
2
7
  class CatchCommand < Command
3
8
  self.allow_in_control = true
4
9
 
@@ -10,23 +15,23 @@ module Byebug
10
15
  excn = @match[1]
11
16
  return info_catch unless excn
12
17
 
13
- if not @match[2]
18
+ if !@match[2]
14
19
  if 'off' == @match[1]
15
20
  Byebug.catchpoints.clear if
16
- confirm("Delete all catchpoints? (y or n) ")
21
+ confirm('Delete all catchpoints? (y or n) ')
17
22
  else
18
- print "Warning #{@match[1]} is not known to be a Class\n" unless
23
+ puts "Warning #{@match[1]} is not known to be a Class" unless
19
24
  bb_eval "#{@match[1]}.is_a?(Class)", get_binding
20
25
  Byebug.add_catchpoint @match[1]
21
- print "Catching exception #{@match[1]}.\n"
26
+ puts "Catching exception #{@match[1]}."
22
27
  end
23
28
  elsif @match[2] != 'off'
24
- errmsg "Off expected. Got #{@match[2]}\n"
29
+ errmsg "Off expected. Got #{@match[2]}"
25
30
  elsif Byebug.catchpoints.member?(@match[1])
26
31
  Byebug.catchpoints.delete @match[1]
27
- print "Catch for exception #{match[1]} removed.\n"
32
+ errmsg "Catch for exception #{match[1]} removed"
28
33
  else
29
- return errmsg "Catch for exception #{@match[1]} not found\n"
34
+ errmsg "Catch for exception #{@match[1]} not found"
30
35
  end
31
36
  end
32
37
 
@@ -36,9 +41,12 @@ module Byebug
36
41
  end
37
42
 
38
43
  def description
39
- %{cat[ch]\t\t\t\tLists catchpoints
40
- cat[ch] off\t\t\tDeletes all catchpoints
41
- cat[ch] <exception> [off]\tEnable/disable handling <exception>.}
44
+ %(cat[ch][ (off|<exception>[ off])]
45
+
46
+ "catch" lists catchpoints.
47
+ "catch off" deletes all catchpoints.
48
+ "catch <exception>" enables handling <exception>.
49
+ "catch <exception> off" disables handling <exception>.)
42
50
  end
43
51
  end
44
52
  end
@@ -1,4 +1,9 @@
1
1
  module Byebug
2
+ #
3
+ # Implements conditions on breakpoints.
4
+ #
5
+ # Adds the ability to stop on breakpoints only under certain conditions.
6
+ #
2
7
  class ConditionCommand < Command
3
8
  self.allow_in_post_mortem = false
4
9
 
@@ -7,24 +12,20 @@ module Byebug
7
12
  end
8
13
 
9
14
  def execute
10
- return print ConditionCommand.help(nil) unless @match[1]
15
+ return puts(ConditionCommand.help) unless @match[1]
11
16
 
12
17
  breakpoints = Byebug.breakpoints.sort_by { |b| b.id }
13
- largest = breakpoints.inject(0) do |tally, b|
14
- tally = b.id if b.id > tally
15
- end
18
+ return errmsg('No breakpoints have been set') unless breakpoints.any?
16
19
 
17
- return errmsg "No breakpoints have been set\n" if 0 == largest
18
- return unless pos = get_int(@match[1], "Condition", 1, largest)
20
+ pos, err = get_int(@match[1], 'Condition', 1, breakpoints.last.id)
21
+ return errmsg(err) unless pos
19
22
 
20
23
  breakpoint = breakpoints.select { |b| b.id == pos }.first
21
24
 
22
- if syntax_valid?(@match[2])
23
- breakpoint.expr = @match[2]
24
- else
25
- return errmsg "Incorrect expression \"#{@match[2]}\", " \
26
- "breakpoint not changed\n"
27
- end
25
+ return errmsg("Incorrect expression \"#{@match[2]}\", " \
26
+ 'breakpoint not changed') unless syntax_valid?(@match[2])
27
+
28
+ breakpoint.expr = @match[2]
28
29
  end
29
30
 
30
31
  class << self
@@ -33,12 +34,12 @@ module Byebug
33
34
  end
34
35
 
35
36
  def description
36
- %{cond[ition] nnn[ expr]
37
+ %(cond[ition] <n>[ expr]
37
38
 
38
- Specify breakpoint number nnn to break only if expr is true. nnn is an
39
- integer and expr is an expression to be evaluated whenever breakpoint
40
- nnn is reached. If no expression is specified, the condition is
41
- removed.}
39
+ Specify breakpoint number <n> to break only if <expr> is true. <n> is
40
+ an integer and <expr> is an expression to be evaluated whenever
41
+ breakpoint <n> is reached. If no expression is specified, the
42
+ condition is removed.)
42
43
  end
43
44
  end
44
45
  end
@@ -1,20 +1,28 @@
1
1
  module Byebug
2
+ #
3
+ # Implements the continue command.
4
+ #
5
+ # Allows the user to continue execution until the next stopping point, a
6
+ # specific line number or until program termination.
7
+ #
2
8
  class ContinueCommand < Command
3
- self.allow_in_post_mortem = true
4
-
5
9
  def regexp
6
10
  /^\s* c(?:ont(?:inue)?)? (?:\s+(\S+))? \s*$/x
7
11
  end
8
12
 
9
13
  def execute
10
- if @match[1] && !@state.context.dead?
14
+ if @match[1]
15
+ num, err = get_int(@match[1], 'Continue', 0, nil)
16
+ return errmsg(err) unless num
17
+
11
18
  filename = File.expand_path(@state.file)
12
- return unless line_number = get_int(@match[1], "Continue", 0, nil, 0)
13
- unless LineCache.trace_line_numbers(filename).member?(line_number)
14
- return errmsg "Line #{line_number} is not a valid stopping point in file\n"
19
+ unless LineCache.trace_line_numbers(filename).member?(num)
20
+ return errmsg("Line #{num} is not a valid stopping point in file")
15
21
  end
16
- Byebug.add_breakpoint filename, line_number
22
+
23
+ Breakpoint.add(filename, num)
17
24
  end
25
+
18
26
  @state.proceed
19
27
  end
20
28
 
@@ -24,9 +32,9 @@ module Byebug
24
32
  end
25
33
 
26
34
  def description
27
- %{c[ont[inue]][ nnn]
35
+ %(c[ont[inue]][ <n>]
28
36
 
29
- Run until program ends, hits a breakpoint or reaches line nnn}
37
+ Run until program ends, hits a breakpoint or reaches line <n>.)
30
38
  end
31
39
  end
32
40
  end
@@ -1,4 +1,7 @@
1
1
  module Byebug
2
+ #
3
+ # Implements breakpoint deletion.
4
+ #
2
5
  class DeleteCommand < Command
3
6
  self.allow_in_post_mortem = false
4
7
  self.allow_in_control = true
@@ -8,16 +11,19 @@ module Byebug
8
11
  end
9
12
 
10
13
  def execute
11
- return errmsg "We are not in a state we can delete breakpoints.\n" unless
12
- @state.context
13
-
14
- if not @match[1]
15
- Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ")
16
- else
17
- @match[1].split(/[ \t]+/).each do |pos|
18
- return unless pos = get_int(pos, "Delete", 1)
19
- errmsg "No breakpoint number %d\n", pos unless
20
- Byebug.remove_breakpoint(pos)
14
+ unless @match[1]
15
+ Byebug.breakpoints.clear if confirm('Delete all breakpoints? (y/n) ')
16
+
17
+ return nil
18
+ end
19
+
20
+ @match[1].split(/[ \t]+/).each do |number|
21
+ pos, err = get_int(number, 'Delete', 1)
22
+
23
+ return errmsg(err) unless pos
24
+
25
+ unless Breakpoint.remove(pos)
26
+ return errmsg("No breakpoint number #{pos}")
21
27
  end
22
28
  end
23
29
  end
@@ -28,10 +34,10 @@ module Byebug
28
34
  end
29
35
 
30
36
  def description
31
- %{del[ete][ nnn...]
37
+ %(del[ete][ nnn...]
32
38
 
33
- Without and argument, deletes all breakpoints. With integer arguments,
34
- it deletes specific breakpoints.}
39
+ Without and argument, deletes all breakpoints. With integer
40
+ arguments, it deletes specific breakpoints.)
35
41
  end
36
42
  end
37
43
  end