byebug 3.5.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +18 -1
- data/.travis.yml +21 -1
- data/CHANGELOG.md +356 -308
- data/CONTRIBUTING.md +31 -15
- data/GUIDE.md +859 -475
- data/Gemfile +8 -10
- data/LICENSE +1 -1
- data/README.md +41 -45
- data/Rakefile +30 -28
- data/byebug.gemspec +18 -18
- data/ext/byebug/breakpoint.c +88 -75
- data/ext/byebug/byebug.c +253 -252
- data/ext/byebug/byebug.h +53 -53
- data/ext/byebug/context.c +188 -159
- data/ext/byebug/extconf.rb +9 -6
- data/ext/byebug/locker.c +53 -11
- data/ext/byebug/threads.c +137 -39
- data/lib/byebug/attacher.rb +7 -2
- data/lib/byebug/breakpoint.rb +30 -0
- data/lib/byebug/command.rb +36 -32
- data/lib/byebug/commands/break.rb +49 -48
- data/lib/byebug/commands/catch.rb +64 -0
- data/lib/byebug/commands/condition.rb +13 -9
- data/lib/byebug/commands/continue.rb +8 -4
- data/lib/byebug/commands/delete.rb +10 -4
- data/lib/byebug/commands/display.rb +33 -25
- data/lib/byebug/commands/edit.rb +18 -13
- data/lib/byebug/commands/enable_disable.rb +26 -24
- data/lib/byebug/commands/eval.rb +77 -35
- data/lib/byebug/commands/finish.rb +9 -5
- data/lib/byebug/commands/frame.rb +66 -125
- data/lib/byebug/commands/help.rb +14 -21
- data/lib/byebug/commands/history.rb +5 -1
- data/lib/byebug/commands/info.rb +41 -106
- data/lib/byebug/commands/interrupt.rb +6 -2
- data/lib/byebug/commands/irb.rb +5 -2
- data/lib/byebug/commands/kill.rb +6 -2
- data/lib/byebug/commands/list.rb +21 -14
- data/lib/byebug/commands/method.rb +17 -9
- data/lib/byebug/commands/pry.rb +13 -3
- data/lib/byebug/commands/quit.rb +10 -5
- data/lib/byebug/commands/restart.rb +12 -19
- data/lib/byebug/commands/save.rb +10 -6
- data/lib/byebug/commands/set.rb +15 -14
- data/lib/byebug/commands/show.rb +8 -8
- data/lib/byebug/commands/source.rb +14 -8
- data/lib/byebug/commands/stepping.rb +15 -29
- data/lib/byebug/commands/threads.rb +73 -49
- data/lib/byebug/commands/tracevar.rb +56 -0
- data/lib/byebug/commands/undisplay.rb +8 -4
- data/lib/byebug/commands/untracevar.rb +38 -0
- data/lib/byebug/commands/var.rb +107 -0
- data/lib/byebug/context.rb +78 -42
- data/lib/byebug/core.rb +78 -40
- data/lib/byebug/helper.rb +58 -42
- data/lib/byebug/history.rb +12 -1
- data/lib/byebug/interface.rb +91 -11
- data/lib/byebug/interfaces/local_interface.rb +12 -19
- data/lib/byebug/interfaces/remote_interface.rb +12 -15
- data/lib/byebug/interfaces/script_interface.rb +14 -18
- data/lib/byebug/interfaces/test_interface.rb +54 -0
- data/lib/byebug/printers/base.rb +64 -0
- data/lib/byebug/printers/plain.rb +53 -0
- data/lib/byebug/processor.rb +20 -1
- data/lib/byebug/processors/command_processor.rb +57 -172
- data/lib/byebug/processors/control_command_processor.rb +16 -43
- data/lib/byebug/remote.rb +13 -7
- data/lib/byebug/runner.rb +102 -54
- data/lib/byebug/setting.rb +45 -68
- data/lib/byebug/settings/autoeval.rb +2 -0
- data/lib/byebug/settings/autoirb.rb +3 -0
- data/lib/byebug/settings/autolist.rb +3 -0
- data/lib/byebug/settings/autosave.rb +2 -0
- data/lib/byebug/settings/basename.rb +2 -0
- data/lib/byebug/settings/callstyle.rb +2 -0
- data/lib/byebug/settings/fullpath.rb +2 -0
- data/lib/byebug/settings/histfile.rb +2 -0
- data/lib/byebug/settings/histsize.rb +2 -0
- data/lib/byebug/settings/linetrace.rb +2 -0
- data/lib/byebug/settings/listsize.rb +2 -0
- data/lib/byebug/settings/post_mortem.rb +7 -2
- data/lib/byebug/settings/stack_on_error.rb +2 -0
- data/lib/byebug/settings/verbose.rb +2 -0
- data/lib/byebug/settings/width.rb +2 -0
- data/lib/byebug/state.rb +12 -0
- data/lib/byebug/states/control_state.rb +26 -0
- data/lib/byebug/states/regular_state.rb +178 -0
- data/lib/byebug/version.rb +1 -1
- metadata +24 -109
- data/lib/byebug/commands/catchpoint.rb +0 -53
- data/lib/byebug/commands/reload.rb +0 -29
- data/lib/byebug/commands/trace.rb +0 -50
- data/lib/byebug/commands/variables.rb +0 -206
- data/lib/byebug/options.rb +0 -46
- data/lib/byebug/settings/autoreload.rb +0 -12
- data/lib/byebug/settings/forcestep.rb +0 -14
- data/lib/byebug/settings/testing.rb +0 -12
- data/lib/byebug/settings/tracing_plus.rb +0 -11
- data/test/commands/break_test.rb +0 -364
- data/test/commands/condition_test.rb +0 -85
- data/test/commands/continue_test.rb +0 -47
- data/test/commands/delete_test.rb +0 -26
- data/test/commands/display_test.rb +0 -37
- data/test/commands/edit_test.rb +0 -52
- data/test/commands/eval_test.rb +0 -89
- data/test/commands/finish_test.rb +0 -74
- data/test/commands/frame_test.rb +0 -223
- data/test/commands/help_test.rb +0 -66
- data/test/commands/history_test.rb +0 -61
- data/test/commands/info_test.rb +0 -238
- data/test/commands/interrupt_test.rb +0 -45
- data/test/commands/irb_test.rb +0 -28
- data/test/commands/kill_test.rb +0 -50
- data/test/commands/list_test.rb +0 -174
- data/test/commands/method_test.rb +0 -52
- data/test/commands/post_mortem_test.rb +0 -71
- data/test/commands/pry_test.rb +0 -26
- data/test/commands/quit_test.rb +0 -53
- data/test/commands/reload_test.rb +0 -39
- data/test/commands/restart_test.rb +0 -46
- data/test/commands/save_test.rb +0 -67
- data/test/commands/set_test.rb +0 -140
- data/test/commands/show_test.rb +0 -76
- data/test/commands/source_test.rb +0 -46
- data/test/commands/stepping_test.rb +0 -192
- data/test/commands/thread_test.rb +0 -164
- data/test/commands/trace_test.rb +0 -71
- data/test/commands/undisplay_test.rb +0 -75
- data/test/commands/variables_test.rb +0 -105
- data/test/debugger_alias_test.rb +0 -7
- data/test/runner_test.rb +0 -150
- data/test/support/matchers.rb +0 -65
- data/test/support/test_interface.rb +0 -59
- data/test/support/utils.rb +0 -122
- data/test/test_helper.rb +0 -58
@@ -1,14 +1,19 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
3
|
+
#
|
4
|
+
# TODO: Implement thread commands as a single command with subcommands, just
|
5
|
+
# like `info`, `var`, `enable` and `disable`. This allows consistent help
|
6
|
+
# format and we can go back to showing help for a single command in the `help`
|
7
|
+
# command.
|
8
|
+
#
|
1
9
|
module Byebug
|
2
10
|
#
|
3
11
|
# Utilities to assist commands related to threads.
|
4
12
|
#
|
5
13
|
module ThreadFunctions
|
6
14
|
def display_context(context, should_show_top_frame = true)
|
7
|
-
|
8
|
-
|
9
|
-
args[:status_flag], args[:debug_flag], args[:id],
|
10
|
-
args[:thread], args[:file_line])
|
11
|
-
puts interp
|
15
|
+
puts pr('thread.context',
|
16
|
+
thread_arguments(context, should_show_top_frame))
|
12
17
|
end
|
13
18
|
|
14
19
|
def thread_arguments(context, should_show_top_frame = true)
|
@@ -18,50 +23,47 @@ module Byebug
|
|
18
23
|
context.thread == Thread.current ? '+' : ' '
|
19
24
|
end
|
20
25
|
debug_flag = context.ignored? ? '!' : ' '
|
26
|
+
|
21
27
|
if should_show_top_frame
|
22
|
-
if context
|
23
|
-
|
24
|
-
line = context.frame_line(0)
|
28
|
+
if context == Byebug.current_context
|
29
|
+
file_line = "#{@state.file}:#{@state.line}"
|
25
30
|
else
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
line = context.thread.backtrace_locations[0].lineno
|
31
|
+
backtrace = context.thread.backtrace_locations
|
32
|
+
if backtrace && backtrace[0]
|
33
|
+
file_line = "#{backtrace[0].path}:#{backtrace[0].lineno}"
|
30
34
|
end
|
31
35
|
end
|
32
|
-
file_line = "#{file}:#{line}"
|
33
36
|
end
|
34
37
|
{
|
35
38
|
status_flag: status_flag,
|
36
39
|
debug_flag: debug_flag,
|
37
40
|
id: context.thnum,
|
38
41
|
thread: context.thread.inspect,
|
39
|
-
file_line: file_line
|
42
|
+
file_line: file_line || ''
|
40
43
|
}
|
41
44
|
end
|
42
45
|
|
43
46
|
def parse_thread_num(subcmd, arg)
|
44
|
-
|
45
|
-
|
46
|
-
thread_num, err = get_int(arg, subcmd, 1)
|
47
|
-
return errmsg(err) unless thread_num
|
47
|
+
thnum, err = get_int(arg, subcmd, 1)
|
48
|
+
return [nil, err] unless thnum
|
48
49
|
|
49
50
|
Byebug.contexts.find { |c| c.thnum == thnum }
|
50
51
|
end
|
51
52
|
|
52
53
|
def parse_thread_num_for_cmd(subcmd, arg)
|
53
|
-
c = parse_thread_num(subcmd, arg)
|
54
|
-
return unless c
|
54
|
+
c, err = parse_thread_num(subcmd, arg)
|
55
55
|
|
56
56
|
case
|
57
|
-
when
|
58
|
-
|
57
|
+
when err
|
58
|
+
[c, err]
|
59
|
+
when c.nil?
|
60
|
+
[nil, pr('thread.errors.no_thread')]
|
59
61
|
when @state.context == c
|
60
|
-
|
62
|
+
[c, pr('thread.errors.current_thread')]
|
61
63
|
when c.ignored?
|
62
|
-
|
64
|
+
[c, pr('thread.errors.wrong_action', subcmd: subcmd, arg: arg)]
|
63
65
|
else
|
64
|
-
c
|
66
|
+
[c, nil]
|
65
67
|
end
|
66
68
|
end
|
67
69
|
end
|
@@ -70,6 +72,8 @@ module Byebug
|
|
70
72
|
# List current threads.
|
71
73
|
#
|
72
74
|
class ThreadListCommand < Command
|
75
|
+
include ThreadFunctions
|
76
|
+
|
73
77
|
self.allow_in_control = true
|
74
78
|
|
75
79
|
def regexp
|
@@ -77,8 +81,13 @@ module Byebug
|
|
77
81
|
end
|
78
82
|
|
79
83
|
def execute
|
80
|
-
|
81
|
-
|
84
|
+
contexts = Byebug.contexts.sort_by(&:thnum)
|
85
|
+
|
86
|
+
thread_list = prc('thread.context', contexts) do |context, _|
|
87
|
+
thread_arguments(context)
|
88
|
+
end
|
89
|
+
|
90
|
+
print(thread_list)
|
82
91
|
end
|
83
92
|
|
84
93
|
class << self
|
@@ -87,7 +96,9 @@ module Byebug
|
|
87
96
|
end
|
88
97
|
|
89
98
|
def description
|
90
|
-
|
99
|
+
prettify <<-EOD
|
100
|
+
th[read] l[ist] Lists all threads.
|
101
|
+
EOD
|
91
102
|
end
|
92
103
|
end
|
93
104
|
end
|
@@ -96,6 +107,8 @@ module Byebug
|
|
96
107
|
# Show current thread.
|
97
108
|
#
|
98
109
|
class ThreadCurrentCommand < Command
|
110
|
+
include ThreadFunctions
|
111
|
+
|
99
112
|
def regexp
|
100
113
|
/^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
|
101
114
|
end
|
@@ -110,7 +123,9 @@ module Byebug
|
|
110
123
|
end
|
111
124
|
|
112
125
|
def description
|
113
|
-
|
126
|
+
prettify <<-EOD
|
127
|
+
th[read] cur[rent] Shows current thread.
|
128
|
+
EOD
|
114
129
|
end
|
115
130
|
end
|
116
131
|
end
|
@@ -119,7 +134,9 @@ module Byebug
|
|
119
134
|
# Stop execution of a thread.
|
120
135
|
#
|
121
136
|
class ThreadStopCommand < Command
|
122
|
-
|
137
|
+
include ThreadFunctions
|
138
|
+
|
139
|
+
self.allow_in_control = true
|
123
140
|
self.allow_in_post_mortem = false
|
124
141
|
|
125
142
|
def regexp
|
@@ -127,8 +144,8 @@ module Byebug
|
|
127
144
|
end
|
128
145
|
|
129
146
|
def execute
|
130
|
-
c = parse_thread_num_for_cmd('thread stop', @match[1])
|
131
|
-
return
|
147
|
+
c, err = parse_thread_num_for_cmd('thread stop', @match[1])
|
148
|
+
return errmsg(err) if err
|
132
149
|
|
133
150
|
c.suspend
|
134
151
|
display_context(c)
|
@@ -140,7 +157,9 @@ module Byebug
|
|
140
157
|
end
|
141
158
|
|
142
159
|
def description
|
143
|
-
|
160
|
+
prettify <<-EOD
|
161
|
+
th[read] stop <n> Stops thread <n>.
|
162
|
+
EOD
|
144
163
|
end
|
145
164
|
end
|
146
165
|
end
|
@@ -149,7 +168,9 @@ module Byebug
|
|
149
168
|
# Resume execution of a thread.
|
150
169
|
#
|
151
170
|
class ThreadResumeCommand < Command
|
152
|
-
|
171
|
+
include ThreadFunctions
|
172
|
+
|
173
|
+
self.allow_in_control = true
|
153
174
|
self.allow_in_post_mortem = false
|
154
175
|
|
155
176
|
def regexp
|
@@ -157,9 +178,10 @@ module Byebug
|
|
157
178
|
end
|
158
179
|
|
159
180
|
def execute
|
160
|
-
c = parse_thread_num_for_cmd('thread resume', @match[1])
|
161
|
-
return
|
162
|
-
return errmsg('
|
181
|
+
c, err = parse_thread_num_for_cmd('thread resume', @match[1])
|
182
|
+
return errmsg(err) if err
|
183
|
+
return errmsg pr('thread.errors.already_running') unless c.suspended?
|
184
|
+
|
163
185
|
c.resume
|
164
186
|
display_context(c)
|
165
187
|
end
|
@@ -170,7 +192,9 @@ module Byebug
|
|
170
192
|
end
|
171
193
|
|
172
194
|
def description
|
173
|
-
|
195
|
+
prettify <<-EOD
|
196
|
+
th[read] resume <n> Resumes thread <n>.
|
197
|
+
EOD
|
174
198
|
end
|
175
199
|
end
|
176
200
|
end
|
@@ -179,24 +203,22 @@ module Byebug
|
|
179
203
|
# Switch execution to a different thread.
|
180
204
|
#
|
181
205
|
class ThreadSwitchCommand < Command
|
182
|
-
|
206
|
+
include ThreadFunctions
|
207
|
+
|
208
|
+
self.allow_in_control = true
|
183
209
|
self.allow_in_post_mortem = false
|
184
210
|
|
185
211
|
def regexp
|
186
|
-
/^\s* th(?:read)? \s+
|
212
|
+
/^\s* th(?:read)? \s+ sw(?:itch)? (?:\s+(\S+))? \s*$/x
|
187
213
|
end
|
188
214
|
|
189
215
|
def execute
|
190
|
-
|
191
|
-
|
192
|
-
end
|
193
|
-
|
194
|
-
c = parse_thread_num_for_cmd('thread switch', @match[1])
|
195
|
-
return unless c
|
216
|
+
c, err = parse_thread_num_for_cmd('thread switch', @match[1])
|
217
|
+
return errmsg(err) if err
|
196
218
|
|
197
219
|
display_context(c)
|
198
|
-
|
199
|
-
c.
|
220
|
+
|
221
|
+
c.switch
|
200
222
|
@state.proceed
|
201
223
|
end
|
202
224
|
|
@@ -206,7 +228,9 @@ module Byebug
|
|
206
228
|
end
|
207
229
|
|
208
230
|
def description
|
209
|
-
|
231
|
+
prettify <<-EOD
|
232
|
+
th[read] sw[itch] <n> Switches thread context to <n>.
|
233
|
+
EOD
|
210
234
|
end
|
211
235
|
end
|
212
236
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
#
|
5
|
+
# Show (and possibily stop) at every line that changes a global variable.
|
6
|
+
#
|
7
|
+
class TracevarCommand < Command
|
8
|
+
self.allow_in_post_mortem = false
|
9
|
+
|
10
|
+
def regexp
|
11
|
+
/^\s* tr(?:acevar)? (?: \s+ (\S+))? # (variable-name)?
|
12
|
+
(?: \s+ (stop|nostop))?
|
13
|
+
\s*$/x
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
var = @match[1]
|
18
|
+
return errmsg(pr('trace.errors.needs_global_variable')) unless var
|
19
|
+
|
20
|
+
unless global_variables.include?(:"#{var}")
|
21
|
+
return errmsg(pr('trace.errors.var_is_not_global', name: var))
|
22
|
+
end
|
23
|
+
|
24
|
+
stop = @match[2] && @match[2] !~ /nostop/
|
25
|
+
|
26
|
+
instance_eval do
|
27
|
+
trace_var(:"#{var}") { |val| on_change(var, val, stop) }
|
28
|
+
end
|
29
|
+
|
30
|
+
puts pr('trace.messages.success', var: var)
|
31
|
+
end
|
32
|
+
|
33
|
+
def on_change(name, value, stop)
|
34
|
+
puts pr('trace.messages.on_change', name: name, value: value)
|
35
|
+
byebug(1, false) if stop
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
def names
|
40
|
+
%w(tracevar)
|
41
|
+
end
|
42
|
+
|
43
|
+
def description
|
44
|
+
prettify <<-EOD
|
45
|
+
tr[acevar] <variable> [[no]stop]
|
46
|
+
|
47
|
+
Start tracing variable <variable>.
|
48
|
+
|
49
|
+
If "stop" is specified, execution will stop every time the variable
|
50
|
+
changes its value. If nothing or "nostop" is specified, execution
|
51
|
+
won't stop, changes will just be logged in byebug's output.
|
52
|
+
EOD
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
1
3
|
module Byebug
|
2
4
|
#
|
3
5
|
# Remove expressions from display list.
|
@@ -15,12 +17,12 @@ module Byebug
|
|
15
17
|
return errmsg(err) unless err.nil?
|
16
18
|
|
17
19
|
unless @state.display[pos - 1]
|
18
|
-
return errmsg(
|
20
|
+
return errmsg(pr('display.errors.undefined', expr: pos))
|
19
21
|
end
|
20
22
|
|
21
23
|
@state.display[pos - 1][0] = nil
|
22
24
|
else
|
23
|
-
return unless confirm(
|
25
|
+
return unless confirm(pr('display.confirmations.clear_all'))
|
24
26
|
|
25
27
|
@state.display.each { |d| d[0] = false }
|
26
28
|
end
|
@@ -32,13 +34,15 @@ module Byebug
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def description
|
35
|
-
|
37
|
+
prettify <<-EOD
|
38
|
+
undisp[lay][ nnn]
|
36
39
|
|
37
40
|
Cancel some expressions to be displayed when program stops. Arguments
|
38
41
|
are the code numbers of the expressions to stop displaying. No
|
39
42
|
argument means cancel all automatic-display expressions. "delete
|
40
43
|
display" has the same effect as this command. Do "info display" to see
|
41
|
-
the current list of code numbers.
|
44
|
+
the current list of code numbers.
|
45
|
+
EOD
|
42
46
|
end
|
43
47
|
end
|
44
48
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
#
|
5
|
+
# Stop tracing a global variable.
|
6
|
+
#
|
7
|
+
class UntracevarCommand < Command
|
8
|
+
self.allow_in_post_mortem = false
|
9
|
+
|
10
|
+
def regexp
|
11
|
+
/^\s* untr(?:acevar)? (?:\s+ (\S+))? \s*$/x
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
var = @match[1]
|
16
|
+
if global_variables.include?(:"#{var}")
|
17
|
+
eval("untrace_var(:\"#{var}\")")
|
18
|
+
puts pr('trace.messages.undo', var: var)
|
19
|
+
else
|
20
|
+
errmsg pr('trace.errors.not_global', var: var)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def names
|
26
|
+
%w(untracevar)
|
27
|
+
end
|
28
|
+
|
29
|
+
def description
|
30
|
+
prettify <<-EOD
|
31
|
+
untr[acevar] <variable>
|
32
|
+
|
33
|
+
Stop tracing global variable <variable>.
|
34
|
+
EOD
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'byebug/command'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
#
|
5
|
+
# Utilities for the var command.
|
6
|
+
#
|
7
|
+
module VarFunctions
|
8
|
+
def var_list(ary, b = get_binding)
|
9
|
+
vars = ary.sort.map do |v|
|
10
|
+
s = begin
|
11
|
+
b.eval(v.to_s).inspect
|
12
|
+
rescue
|
13
|
+
begin
|
14
|
+
b.eval(v.to_s).to_s
|
15
|
+
rescue
|
16
|
+
'*Error in evaluation*'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
[v, s]
|
20
|
+
end
|
21
|
+
puts prv(vars)
|
22
|
+
end
|
23
|
+
|
24
|
+
def var_global(_str = nil)
|
25
|
+
globals = global_variables.reject do |v|
|
26
|
+
[:$IGNORECASE, :$=, :$KCODE, :$-K, :$binding].include?(v)
|
27
|
+
end
|
28
|
+
|
29
|
+
var_list(globals)
|
30
|
+
end
|
31
|
+
|
32
|
+
def var_instance(str)
|
33
|
+
obj = bb_warning_eval(str || 'self')
|
34
|
+
var_list(obj.instance_variables, obj.instance_eval { binding })
|
35
|
+
end
|
36
|
+
|
37
|
+
def var_constant(str)
|
38
|
+
str ||= 'self.class'
|
39
|
+
obj = bb_warning_eval(str)
|
40
|
+
is_mod = obj.is_a?(Module)
|
41
|
+
return errmsg(pr('variable.errors.not_module', object: str)) unless is_mod
|
42
|
+
|
43
|
+
constants = bb_eval("#{str}.constants")
|
44
|
+
puts prv(constants.sort.map { |c| [c, obj.const_get(c)] })
|
45
|
+
end
|
46
|
+
|
47
|
+
def var_local(_str = nil)
|
48
|
+
_self = @state.context.frame_self(@state.frame)
|
49
|
+
locals = @state.context.frame_locals
|
50
|
+
puts prv(locals.keys.sort.map { |k| [k, locals[k]] })
|
51
|
+
end
|
52
|
+
|
53
|
+
def var_all(_str = nil)
|
54
|
+
var_global
|
55
|
+
var_instance('self')
|
56
|
+
var_local
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Show variables and its values.
|
62
|
+
#
|
63
|
+
class VarCommand < Command
|
64
|
+
include VarFunctions
|
65
|
+
|
66
|
+
Subcommands = [
|
67
|
+
['constant', 2, 'Show constants of an object'],
|
68
|
+
['global', 1, 'Show global variables'],
|
69
|
+
['instance', 1, 'Show instance variables of self or a specific object'],
|
70
|
+
['local', 1, 'Show local variables in current scope'],
|
71
|
+
['all', 1, 'Shows local, global and instance variables of self']
|
72
|
+
].map do |name, min, help|
|
73
|
+
Subcmd.new(name, min, help)
|
74
|
+
end
|
75
|
+
|
76
|
+
def regexp
|
77
|
+
/^\s* v(?:ar)? (?: \s+(\S+) (?:\s(\S+))? )? \s*$/x
|
78
|
+
end
|
79
|
+
|
80
|
+
def execute
|
81
|
+
return puts(self.class.help) unless @match[1]
|
82
|
+
|
83
|
+
subcmd = Command.find(Subcommands, @match[1])
|
84
|
+
return errmsg("Unknown var command #{@match[1]}\n") unless subcmd
|
85
|
+
|
86
|
+
if @state.context
|
87
|
+
send("var_#{subcmd.name}", @match[2])
|
88
|
+
else
|
89
|
+
errmsg "'var #{subcmd.name}' not available without a context.\n"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class << self
|
94
|
+
def names
|
95
|
+
%w(var)
|
96
|
+
end
|
97
|
+
|
98
|
+
def description
|
99
|
+
prettify <<-EOD
|
100
|
+
[v]ar
|
101
|
+
|
102
|
+
Show variables and its values.
|
103
|
+
EOD
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|