byebug 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/GUIDE.md +209 -0
- data/README.md +11 -2
- data/Rakefile +12 -0
- data/ext/byebug/byebug.c +50 -53
- data/ext/byebug/context.c +0 -24
- data/lib/byebug.rb +23 -7
- data/lib/byebug/command.rb +35 -24
- data/lib/byebug/commands/breakpoints.rb +24 -35
- data/lib/byebug/commands/catchpoint.rb +13 -17
- data/lib/byebug/commands/condition.rb +14 -19
- data/lib/byebug/commands/continue.rb +5 -7
- data/lib/byebug/commands/display.rb +3 -3
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/enable.rb +18 -45
- data/lib/byebug/commands/eval.rb +1 -1
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/frame.rb +24 -22
- data/lib/byebug/commands/info.rb +91 -122
- data/lib/byebug/commands/jump.rb +3 -8
- data/lib/byebug/commands/list.rb +2 -2
- data/lib/byebug/commands/method.rb +6 -8
- data/lib/byebug/commands/save.rb +1 -1
- data/lib/byebug/commands/set.rb +0 -12
- data/lib/byebug/commands/show.rb +9 -21
- data/lib/byebug/commands/variables.rb +3 -3
- data/lib/byebug/context.rb +13 -2
- data/lib/byebug/interface.rb +13 -7
- data/lib/byebug/processor.rb +23 -25
- data/lib/byebug/version.rb +1 -1
- data/old_doc/primes.rb +1 -4
- data/test/continue_test.rb +2 -9
- data/test/examples/list.rb +1 -1
- data/test/examples/trace.rb +1 -0
- data/test/help_test.rb +1 -1
- data/test/info_test.rb +3 -3
- data/test/list_test.rb +7 -1
- data/test/method_test.rb +0 -1
- data/test/show_test.rb +8 -0
- data/test/support/matchers.rb +4 -2
- data/test/trace_test.rb +18 -1
- metadata +2 -2
data/lib/byebug.rb
CHANGED
@@ -247,7 +247,6 @@ class Module
|
|
247
247
|
end
|
248
248
|
|
249
249
|
module Kernel
|
250
|
-
|
251
250
|
##
|
252
251
|
# Enters byebug after _steps_ line events occur.
|
253
252
|
#
|
@@ -267,13 +266,30 @@ module Kernel
|
|
267
266
|
end
|
268
267
|
end
|
269
268
|
alias breakpoint byebug unless respond_to?(:breakpoint)
|
269
|
+
end
|
270
270
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
271
|
+
module Rails
|
272
|
+
module Rack
|
273
|
+
class Debugger
|
274
|
+
def initialize(app)
|
275
|
+
@app = app
|
276
|
+
|
277
|
+
# clear ARGV so that rails server options aren't passed to IRB
|
278
|
+
ARGV.clear
|
279
|
+
|
280
|
+
require 'byebug'
|
281
|
+
|
282
|
+
::Byebug.start
|
283
|
+
puts "=> Byebug enabled"
|
284
|
+
rescue LoadError
|
285
|
+
puts "You're missing the 'byebug' gem. Add it to your Gemfile, bundle " \
|
286
|
+
"it and try again."
|
287
|
+
exit(1)
|
288
|
+
end
|
289
|
+
|
290
|
+
def call(env)
|
291
|
+
@app.call(env)
|
292
|
+
end
|
277
293
|
end
|
278
294
|
end
|
279
295
|
end
|
data/lib/byebug/command.rb
CHANGED
@@ -30,24 +30,6 @@ module Byebug
|
|
30
30
|
end
|
31
31
|
return nil
|
32
32
|
end
|
33
|
-
|
34
|
-
##
|
35
|
-
# Build formatted list of subcmds
|
36
|
-
#
|
37
|
-
def format_subcmds(subcmds)
|
38
|
-
cmd_name = self.class.names.join("|")
|
39
|
-
s = "\n" \
|
40
|
-
"--\n" \
|
41
|
-
"List of \"#{cmd_name}\" subcommands:\n" \
|
42
|
-
"--\n"
|
43
|
-
width = subcmds.map(&:name).max_by(&:size).size
|
44
|
-
for subcmd in subcmds do
|
45
|
-
s += sprintf \
|
46
|
-
"%s %-#{width}s -- %s\n", cmd_name, subcmd.name, subcmd.short_help
|
47
|
-
end
|
48
|
-
return s
|
49
|
-
end
|
50
|
-
|
51
33
|
end
|
52
34
|
|
53
35
|
# Root dir for byebug
|
@@ -74,7 +56,37 @@ module Byebug
|
|
74
56
|
output = description.split("\n").map{|l| l.gsub(/^ +/, '')}
|
75
57
|
output.shift if output.first && output.first.empty?
|
76
58
|
output.pop if output.last && output.last.empty?
|
77
|
-
output.join("\n") + "\n"
|
59
|
+
output = output.join("\n") + "\n"
|
60
|
+
|
61
|
+
if defined? self::Subcommands
|
62
|
+
return output += format_subcmds unless args and args[1]
|
63
|
+
output += format_subcmd(args[1])
|
64
|
+
end
|
65
|
+
|
66
|
+
return output
|
67
|
+
end
|
68
|
+
|
69
|
+
def format_subcmd(subcmd_name)
|
70
|
+
subcmd = find(self::Subcommands, subcmd_name)
|
71
|
+
return "Invalid \"#{names.join("|")}\" " \
|
72
|
+
"subcommand \"#{args[1]}\"." unless subcmd
|
73
|
+
|
74
|
+
return "#{subcmd.short_help}.\n" \
|
75
|
+
"#{subcmd.long_help || '' }"
|
76
|
+
end
|
77
|
+
|
78
|
+
def format_subcmds
|
79
|
+
cmd_name = names.join("|")
|
80
|
+
s = "\n" \
|
81
|
+
"--\n" \
|
82
|
+
"List of \"#{cmd_name}\" subcommands:\n" \
|
83
|
+
"--\n"
|
84
|
+
width = self::Subcommands.map(&:name).max_by(&:size).size
|
85
|
+
for subcmd in self::Subcommands do
|
86
|
+
s += sprintf \
|
87
|
+
"%s %-#{width}s -- %s\n", cmd_name, subcmd.name, subcmd.short_help
|
88
|
+
end
|
89
|
+
return s
|
78
90
|
end
|
79
91
|
|
80
92
|
def inherited(klass)
|
@@ -185,9 +197,9 @@ module Byebug
|
|
185
197
|
rescue StandardError, ScriptError => e
|
186
198
|
if Command.settings[:stack_trace_on_error]
|
187
199
|
at = eval("caller(1)", b)
|
188
|
-
print "
|
200
|
+
print "#{at.shift}:#{e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')}"
|
189
201
|
for i in at
|
190
|
-
print "\tfrom
|
202
|
+
print "\tfrom #{i}\n"
|
191
203
|
end
|
192
204
|
else
|
193
205
|
print "#{e.class} Exception: #{e.message}\n"
|
@@ -212,9 +224,8 @@ module Byebug
|
|
212
224
|
end
|
213
225
|
end
|
214
226
|
|
215
|
-
def get_binding
|
216
|
-
@state.context ? @state.context.frame_binding(
|
217
|
-
TOPLEVEL_BINDING
|
227
|
+
def get_binding pos = @state.frame_pos
|
228
|
+
@state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING
|
218
229
|
end
|
219
230
|
end
|
220
231
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Byebug
|
2
2
|
|
3
3
|
# Implements byebug "break" command.
|
4
|
-
class
|
4
|
+
class BreakCommand < Command
|
5
5
|
self.allow_in_control = true
|
6
6
|
|
7
7
|
def regexp
|
@@ -14,8 +14,7 @@ module Byebug
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def execute
|
17
|
-
return print
|
18
|
-
AddBreakpoint.names.include?(@match[0])
|
17
|
+
return print self.class.help(nil) if self.class.names.include?(@match[0])
|
19
18
|
|
20
19
|
if @match[1]
|
21
20
|
line, _, _, expr = @match.captures
|
@@ -61,27 +60,20 @@ module Byebug
|
|
61
60
|
line = line.to_i
|
62
61
|
if LineCache.cache(brkpt_filename, Command.settings[:autoreload])
|
63
62
|
last_line = LineCache.size(brkpt_filename)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
unless LineCache.trace_line_numbers(brkpt_filename).member?(line)
|
71
|
-
errmsg \
|
72
|
-
"Line %d is not a stopping point in file %s\n",
|
73
|
-
line, brkpt_filename
|
74
|
-
return
|
75
|
-
end
|
63
|
+
return errmsg "There are only #{last_line} lines in file " \
|
64
|
+
"#{brkpt_filename}\n" if line > last_line
|
65
|
+
|
66
|
+
return errmsg "Line #{line} is not a stopping point in file " \
|
67
|
+
"#{brkpt_filename}\n" unless
|
68
|
+
LineCache.trace_line_numbers(brkpt_filename).member?(line)
|
76
69
|
else
|
77
|
-
errmsg
|
70
|
+
errmsg "No source file named #{brkpt_filename}\n"
|
78
71
|
return unless confirm("Set breakpoint anyway? (y/n) ")
|
79
72
|
end
|
80
73
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
74
|
+
return errmsg "We are not in a state we can add breakpoints.\n" unless
|
75
|
+
@state.context
|
76
|
+
|
85
77
|
b = Byebug.add_breakpoint brkpt_filename, line, expr
|
86
78
|
print "Created breakpoint #{b.id} at " \
|
87
79
|
"#{CommandProcessor.canonic_file(brkpt_filename)}:#{line.to_s}\n"
|
@@ -114,7 +106,7 @@ module Byebug
|
|
114
106
|
end
|
115
107
|
|
116
108
|
# Implements byebug "delete" command.
|
117
|
-
class
|
109
|
+
class DeleteCommand < Command
|
118
110
|
self.allow_in_control = true
|
119
111
|
|
120
112
|
def regexp
|
@@ -122,19 +114,16 @@ module Byebug
|
|
122
114
|
end
|
123
115
|
|
124
116
|
def execute
|
125
|
-
return errmsg "We are not in a state we can delete breakpoints.\n" unless
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
117
|
+
return errmsg "We are not in a state we can delete breakpoints.\n" unless
|
118
|
+
@state.context
|
119
|
+
|
120
|
+
if not @match[1]
|
121
|
+
Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ")
|
131
122
|
else
|
132
|
-
|
133
|
-
pos = get_int(pos, "Delete", 1)
|
134
|
-
|
135
|
-
|
136
|
-
errmsg "No breakpoint number %d\n", pos
|
137
|
-
end
|
123
|
+
@match[1].split(/[ \t]+/).each do |pos|
|
124
|
+
return unless pos = get_int(pos, "Delete", 1)
|
125
|
+
errmsg "No breakpoint number %d\n", pos unless
|
126
|
+
Byebug.remove_breakpoint(pos)
|
138
127
|
end
|
139
128
|
end
|
140
129
|
end
|
@@ -148,8 +137,8 @@ module Byebug
|
|
148
137
|
%{
|
149
138
|
del[ete][ nnn...]
|
150
139
|
|
151
|
-
Without
|
152
|
-
deletes specific breakpoints.
|
140
|
+
Without and argument, deletes all breakpoints. With integer arguments,
|
141
|
+
it deletes specific breakpoints.
|
153
142
|
}
|
154
143
|
end
|
155
144
|
end
|
@@ -11,29 +11,25 @@ module Byebug
|
|
11
11
|
|
12
12
|
def execute
|
13
13
|
excn = @match[1]
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# One arg given.
|
19
|
-
if 'off' == excn
|
14
|
+
return info_catch unless excn
|
15
|
+
|
16
|
+
if not @match[2]
|
17
|
+
if 'off' == @match[1]
|
20
18
|
Byebug.catchpoints.clear if
|
21
19
|
confirm("Delete all catchpoints? (y or n) ")
|
22
20
|
else
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Byebug.add_catchpoint(excn)
|
28
|
-
print "Catch exception %s.\n", excn
|
21
|
+
print "Warning #{@match[1]} is not known to be a Class\n" unless
|
22
|
+
debug_eval "#{@match[1]}.is_a?(Class)", get_binding
|
23
|
+
Byebug.add_catchpoint @match[1]
|
24
|
+
print "Catch exception #{@match[1]}.\n"
|
29
25
|
end
|
30
26
|
elsif @match[2] != 'off'
|
31
|
-
errmsg "Off expected. Got
|
32
|
-
elsif Byebug.catchpoints.member?(
|
33
|
-
Byebug.catchpoints.delete
|
34
|
-
print "Catch for exception
|
27
|
+
errmsg "Off expected. Got #{@match[2]}\n"
|
28
|
+
elsif Byebug.catchpoints.member?(@match[1])
|
29
|
+
Byebug.catchpoints.delete @match[1]
|
30
|
+
print "Catch for exception #{match[1]} removed.\n"
|
35
31
|
else
|
36
|
-
errmsg "Catch for exception
|
32
|
+
return errmsg "Catch for exception #{@match[1]} not found\n"
|
37
33
|
end
|
38
34
|
end
|
39
35
|
|
@@ -7,26 +7,21 @@ module Byebug
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def execute
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
breakpoints = Byebug.breakpoints.sort_by{|b| b.id }
|
14
|
-
largest = breakpoints.inject(0) do |tally, b|
|
15
|
-
tally = b.id if b.id > tally
|
16
|
-
end
|
17
|
-
if 0 == largest
|
18
|
-
print "No breakpoints have been set.\n"
|
19
|
-
return
|
20
|
-
end
|
21
|
-
pos = get_int(@match[1], "Condition", 1, largest)
|
22
|
-
return unless pos
|
23
|
-
breakpoints.each do |b|
|
24
|
-
if b.id == pos
|
25
|
-
b.expr = @match[2].empty? ? nil : @match[2]
|
26
|
-
break
|
27
|
-
end
|
28
|
-
end
|
10
|
+
return errmsg "\"condition\" must be followed by " \
|
11
|
+
"breakpoint number and expression\n" unless @match[1]
|
29
12
|
|
13
|
+
breakpoints = Byebug.breakpoints.sort_by{|b| b.id }
|
14
|
+
largest = breakpoints.inject(0) do |tally, b|
|
15
|
+
tally = b.id if b.id > tally
|
16
|
+
end
|
17
|
+
|
18
|
+
return print "No breakpoints have been set.\n" if 0 == largest
|
19
|
+
return unless pos = get_int(@match[1], "Condition", 1, largest)
|
20
|
+
breakpoints.each do |b|
|
21
|
+
if b.id == pos
|
22
|
+
b.expr = @match[2].empty? ? nil : @match[2]
|
23
|
+
break
|
24
|
+
end
|
30
25
|
end
|
31
26
|
end
|
32
27
|
|
@@ -12,13 +12,11 @@ module Byebug
|
|
12
12
|
def execute
|
13
13
|
if @match[1] && !@state.context.dead?
|
14
14
|
filename = File.expand_path(@state.file)
|
15
|
-
line_number = get_int(@match[1], "Continue", 0, nil, 0)
|
16
|
-
return
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
return
|
21
|
-
end
|
15
|
+
return unless line_number = get_int(@match[1], "Continue", 0, nil, 0)
|
16
|
+
return errmsg "Line #{line_number} is not a stopping point in file " \
|
17
|
+
"\"#{filename}\"\n" unless
|
18
|
+
LineCache.trace_line_numbers(filename).member?(line_number)
|
19
|
+
|
22
20
|
Byebug.add_breakpoint filename, line_number
|
23
21
|
end
|
24
22
|
@state.proceed
|
@@ -2,7 +2,7 @@ module Byebug
|
|
2
2
|
|
3
3
|
module DisplayFunctions
|
4
4
|
def display_expression(exp)
|
5
|
-
print "
|
5
|
+
print "#{exp} = #{debug_silent_eval(exp).to_s}\n"
|
6
6
|
end
|
7
7
|
|
8
8
|
def active_display_expressions?
|
@@ -13,7 +13,7 @@ module Byebug
|
|
13
13
|
n = 1
|
14
14
|
for d in @state.display
|
15
15
|
if d[0]
|
16
|
-
print "
|
16
|
+
print "#{n}: "
|
17
17
|
display_expression(d[1])
|
18
18
|
end
|
19
19
|
n += 1
|
@@ -29,7 +29,7 @@ module Byebug
|
|
29
29
|
def execute
|
30
30
|
exp = @match[1]
|
31
31
|
@state.display.push [true, exp]
|
32
|
-
print "
|
32
|
+
print "#{@state.display.size}: "
|
33
33
|
display_expression(exp)
|
34
34
|
end
|
35
35
|
|
data/lib/byebug/commands/edit.rb
CHANGED
@@ -64,18 +64,16 @@ module Byebug
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def execute
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
return errmsg "\"enable\" must be followed by \"display\", " \
|
68
|
+
"\"breakpoints\" or breakpoint numbers.\n" unless @match[1]
|
69
|
+
|
70
|
+
args = @match[1].split(/[ \t]+/)
|
71
|
+
param = args.shift
|
72
|
+
subcmd = find(Subcommands, param)
|
73
|
+
if subcmd
|
74
|
+
send("enable_#{subcmd.name}", args)
|
70
75
|
else
|
71
|
-
args
|
72
|
-
param = args.shift
|
73
|
-
subcmd = find(Subcommands, param)
|
74
|
-
if subcmd
|
75
|
-
send("enable_#{subcmd.name}", args)
|
76
|
-
else
|
77
|
-
send('enable_breakpoints', args.unshift(param))
|
78
|
-
end
|
76
|
+
send('enable_breakpoints', args.unshift(param))
|
79
77
|
end
|
80
78
|
end
|
81
79
|
|
@@ -87,17 +85,6 @@ module Byebug
|
|
87
85
|
enable_disable_display('Enable', args)
|
88
86
|
end
|
89
87
|
|
90
|
-
def help
|
91
|
-
if args[1]
|
92
|
-
subcmd = find(Subcommands, args[1])
|
93
|
-
return "Invalid \"enable\" subcommand \"#{args[1]}\"." unless subcmd
|
94
|
-
str = subcmd.short_help + '.'
|
95
|
-
str += '\n' + subcmd.long_help if subcmd.long_help
|
96
|
-
return str
|
97
|
-
end
|
98
|
-
EnableCommand.description + format_subcmds(Subcommands)
|
99
|
-
end
|
100
|
-
|
101
88
|
class << self
|
102
89
|
def names
|
103
90
|
%w(enable)
|
@@ -131,18 +118,16 @@ module Byebug
|
|
131
118
|
end
|
132
119
|
|
133
120
|
def execute
|
134
|
-
|
135
|
-
|
136
|
-
|
121
|
+
return errmsg "\"disable\" must be followed by \"display\", " \
|
122
|
+
"\"breakpoints\" or breakpoint numbers.\n" unless @match[1]
|
123
|
+
|
124
|
+
args = @match[1].split(/[ \t]+/)
|
125
|
+
param = args.shift
|
126
|
+
subcmd = find(Subcommands, param)
|
127
|
+
if subcmd
|
128
|
+
send("disable_#{subcmd.name}", args)
|
137
129
|
else
|
138
|
-
args
|
139
|
-
param = args.shift
|
140
|
-
subcmd = find(Subcommands, param)
|
141
|
-
if subcmd
|
142
|
-
send("disable_#{subcmd.name}", args)
|
143
|
-
else
|
144
|
-
send('disable_breakpoints', args.unshift(param))
|
145
|
-
end
|
130
|
+
send('disable_breakpoints', args.unshift(param))
|
146
131
|
end
|
147
132
|
end
|
148
133
|
|
@@ -154,18 +139,6 @@ module Byebug
|
|
154
139
|
enable_disable_display('Disable', args)
|
155
140
|
end
|
156
141
|
|
157
|
-
def help(args)
|
158
|
-
if args[1]
|
159
|
-
subcmd = find(Subcommands, args[1])
|
160
|
-
return "Invalid \"disable\" subcommand \"#{args[1]}\"." unless subcmd
|
161
|
-
|
162
|
-
str = subcmd.short_help + '.'
|
163
|
-
str += '\n' + subcmd.long_help if subcmd.long_help
|
164
|
-
return str
|
165
|
-
end
|
166
|
-
DisableCommand.description + format_subcmds(Subcommads)
|
167
|
-
end
|
168
|
-
|
169
142
|
class << self
|
170
143
|
def names
|
171
144
|
%w(disable)
|