byebug 3.5.1 → 4.0.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.
- 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
|