byebug 3.2.0 → 3.3.0

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 (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