byebug 1.0.2 → 1.0.3
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/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/bin/byebug +1 -2
- data/byebug.gemspec +1 -1
- data/ext/byebug/byebug.c +50 -35
- data/ext/byebug/context.c +99 -45
- data/lib/byebug.rb +5 -10
- data/lib/byebug/command.rb +20 -12
- data/lib/byebug/commands/breakpoints.rb +1 -1
- data/lib/byebug/commands/control.rb +14 -21
- data/lib/byebug/commands/display.rb +4 -4
- data/lib/byebug/commands/enable.rb +20 -19
- data/lib/byebug/commands/eval.rb +1 -1
- data/lib/byebug/commands/finish.rb +4 -5
- data/lib/byebug/commands/info.rb +118 -116
- data/lib/byebug/commands/list.rb +72 -48
- data/lib/byebug/commands/reload.rb +4 -3
- data/lib/byebug/commands/set.rb +7 -16
- data/lib/byebug/commands/show.rb +2 -2
- data/lib/byebug/commands/threads.rb +7 -6
- data/lib/byebug/context.rb +10 -2
- data/lib/byebug/helper.rb +3 -3
- data/lib/byebug/processor.rb +1 -1
- data/lib/byebug/version.rb +1 -1
- data/old_doc/byebug.texi +45 -51
- data/test/breakpoints_test.rb +180 -195
- data/test/display_test.rb +59 -53
- data/test/eval_test.rb +0 -2
- data/test/examples/info.rb +5 -5
- data/test/examples/info_threads.rb +1 -1
- data/test/finish_test.rb +16 -15
- data/test/info_test.rb +9 -10
- data/test/irb_test.rb +64 -65
- data/test/list_test.rb +76 -50
- data/test/method_test.rb +10 -5
- data/test/post_mortem_test.rb +27 -25
- data/test/reload_test.rb +31 -31
- data/test/restart_test.rb +106 -110
- data/test/show_test.rb +8 -16
- data/test/stepping_test.rb +4 -2
- data/test/support/test_dsl.rb +37 -76
- data/test/test_helper.rb +0 -1
- data/test/variables_test.rb +9 -12
- metadata +4 -4
@@ -22,7 +22,7 @@ module Byebug
|
|
22
22
|
if expr
|
23
23
|
if expr !~ /^\s*if\s+(.+)/
|
24
24
|
if file or line
|
25
|
-
errmsg "Expecting
|
25
|
+
errmsg "Expecting \"if\" in breakpoint condition; got: #{expr}.\n"
|
26
26
|
else
|
27
27
|
errmsg "Invalid breakpoint location: #{expr}.\n"
|
28
28
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Byebug
|
2
2
|
|
3
|
-
class RestartCommand < Command
|
3
|
+
class RestartCommand < Command
|
4
4
|
self.allow_in_control = true
|
5
5
|
|
6
6
|
def regexp
|
@@ -12,28 +12,24 @@ module Byebug
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def execute
|
15
|
-
|
16
|
-
|
17
|
-
return
|
18
|
-
end
|
15
|
+
return errmsg "Don't know name of debugged program\n" unless
|
16
|
+
defined? Byebug::PROG_SCRIPT
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
return
|
23
|
-
end
|
18
|
+
return errmsg "Ruby program #{Byebug::PROG_SCRIPT} doesn't exist\n" unless
|
19
|
+
File.exist?(File.expand_path(Byebug::PROG_SCRIPT))
|
24
20
|
|
25
|
-
if not defined? Byebug::
|
21
|
+
if not defined? Byebug::BYEBUG_SCRIPT
|
26
22
|
print "Byebug was not called from the outset...\n"
|
27
23
|
if not File.executable?(Byebug::PROG_SCRIPT)
|
28
24
|
print "Ruby program #{Byebug::PROG_SCRIPT} not executable... " \
|
29
25
|
"We'll add a call to Ruby.\n"
|
30
26
|
ruby = begin defined?(Gem) ? Gem.ruby : "ruby" rescue "ruby" end
|
31
|
-
|
27
|
+
cmd = "#{ruby} -I#{$:.join(' -I')} #{Byebug::PROG_SCRIPT}"
|
32
28
|
else
|
33
|
-
|
29
|
+
cmd = Byebug::PROG_SCRIPT
|
34
30
|
end
|
35
31
|
else
|
36
|
-
|
32
|
+
cmd = Byebug::BYEBUG_SCRIPT
|
37
33
|
end
|
38
34
|
|
39
35
|
begin
|
@@ -43,16 +39,13 @@ module Byebug
|
|
43
39
|
end
|
44
40
|
|
45
41
|
if @match[1]
|
46
|
-
|
42
|
+
cmd += " #{@match[1]}"
|
43
|
+
elsif not defined? Command.settings[:argv]
|
44
|
+
return errmsg "Arguments not set. Use 'set args' to set them.\n"
|
47
45
|
else
|
48
|
-
|
49
|
-
|
50
|
-
return
|
51
|
-
else
|
52
|
-
argv = Command.settings[:argv]
|
53
|
-
end
|
46
|
+
require 'shellwords'
|
47
|
+
cmd += " #{Command.settings[:argv].compact.shelljoin}"
|
54
48
|
end
|
55
|
-
cmd = "#{byebug_script} #{argv.compact.join(' ')}"
|
56
49
|
|
57
50
|
# An execv would be preferable to the "exec" below.
|
58
51
|
print "Re exec'ing:\n\t#{cmd}\n"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Byebug
|
2
2
|
|
3
|
-
module DisplayFunctions
|
3
|
+
module DisplayFunctions
|
4
4
|
|
5
5
|
def display_expression(exp)
|
6
6
|
print "%s = %s\n", exp, debug_silent_eval(exp).to_s
|
@@ -22,7 +22,7 @@ module Byebug
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
class AddDisplayCommand < Command
|
25
|
+
class AddDisplayCommand < Command
|
26
26
|
def regexp
|
27
27
|
/^\s*disp(?:lay)?\s+(.+)$/
|
28
28
|
end
|
@@ -47,7 +47,7 @@ module Byebug
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
class DisplayCommand < Command
|
50
|
+
class DisplayCommand < Command
|
51
51
|
def self.always_run
|
52
52
|
Byebug.annotate = 0 unless Byebug.annotate
|
53
53
|
if Byebug.annotate > 1
|
@@ -78,7 +78,7 @@ module Byebug
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
class DeleteDisplayCommand < Command
|
81
|
+
class DeleteDisplayCommand < Command
|
82
82
|
|
83
83
|
def regexp
|
84
84
|
/^\s* undisp(?:lay)? \s* (?:(\S+))?$/x
|
@@ -16,14 +16,15 @@ module Byebug
|
|
16
16
|
return nil unless pos
|
17
17
|
breakpoints.each do |b|
|
18
18
|
if b.id == pos
|
19
|
-
enabled = (
|
19
|
+
enabled = ('Enable' == is_enable)
|
20
20
|
if enabled
|
21
21
|
unless syntax_valid?(b.expr)
|
22
|
-
errmsg
|
22
|
+
errmsg "Expression \"#{b.expr}\" syntactically incorrect; " \
|
23
|
+
"breakpoint remains disabled.\n"
|
23
24
|
break
|
24
25
|
end
|
25
26
|
end
|
26
|
-
b.enabled = (
|
27
|
+
b.enabled = ('Enable' == is_enable)
|
27
28
|
break
|
28
29
|
end
|
29
30
|
end
|
@@ -38,7 +39,7 @@ module Byebug
|
|
38
39
|
args.each do |pos|
|
39
40
|
pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
|
40
41
|
return nil unless pos
|
41
|
-
@state.display[pos-1][0] = (
|
42
|
+
@state.display[pos-1][0] = ('Enable' == is_enable)
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -49,11 +50,11 @@ module Byebug
|
|
49
50
|
[
|
50
51
|
['breakpoints', 2, 'Enable specified breakpoints',
|
51
52
|
'Give breakpoint numbers (separated by spaces) as arguments. This is ' \
|
52
|
-
'used to cancel the effect of the
|
53
|
+
'used to cancel the effect of the "disable" command.'],
|
53
54
|
['display', 2,
|
54
55
|
'Enable some expressions to be displayed when program stops',
|
55
56
|
'Arguments are the code numbers of the expressions to resume ' \
|
56
|
-
'displaying. Do
|
57
|
+
'displaying. Do "info display" to see the current list of code ' \
|
57
58
|
'numbers.'],
|
58
59
|
].map do |name, min, short_help, long_help|
|
59
60
|
SubcmdStruct.new(name, min, short_help, long_help)
|
@@ -65,8 +66,8 @@ module Byebug
|
|
65
66
|
|
66
67
|
def execute
|
67
68
|
if not @match[1]
|
68
|
-
errmsg "\"enable\" must be followed \"display\", \"breakpoints\""
|
69
|
-
|
69
|
+
errmsg "\"enable\" must be followed by \"display\", \"breakpoints\" " \
|
70
|
+
"or breakpoint numbers.\n"
|
70
71
|
else
|
71
72
|
args = @match[1].split(/[ \t]+/)
|
72
73
|
param = args.shift
|
@@ -74,17 +75,17 @@ module Byebug
|
|
74
75
|
if subcmd
|
75
76
|
send("enable_#{subcmd.name}", args)
|
76
77
|
else
|
77
|
-
send(
|
78
|
+
send('enable_breakpoints', args.unshift(param))
|
78
79
|
end
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
82
83
|
def enable_breakpoints(args)
|
83
|
-
enable_disable_breakpoints(
|
84
|
+
enable_disable_breakpoints('Enable', args)
|
84
85
|
end
|
85
86
|
|
86
87
|
def enable_display(args)
|
87
|
-
enable_disable_display(
|
88
|
+
enable_disable_display('Enable', args)
|
88
89
|
end
|
89
90
|
|
90
91
|
class << self
|
@@ -99,7 +100,7 @@ module Byebug
|
|
99
100
|
return "Invalid \"enable\" subcommand \"#{args[1]}\"." unless subcmd
|
100
101
|
|
101
102
|
str = subcmd.short_help + '.'
|
102
|
-
str +=
|
103
|
+
str += '\n' + subcmd.long_help if subcmd.long_help
|
103
104
|
return str
|
104
105
|
end
|
105
106
|
|
@@ -127,7 +128,7 @@ module Byebug
|
|
127
128
|
'breakpoint is not forgotten, but has no effect until reenabled.'],
|
128
129
|
['display', 1, 'Disable some display expressions when program stops',
|
129
130
|
'Arguments are the code numbers of the expressions to stop ' \
|
130
|
-
'displaying. Do
|
131
|
+
'displaying. Do "info display" to see the current list of code ' \
|
131
132
|
'numbers.'],
|
132
133
|
].map do |name, min, short_help, long_help|
|
133
134
|
SubcmdStruct.new(name, min, short_help, long_help)
|
@@ -139,8 +140,8 @@ module Byebug
|
|
139
140
|
|
140
141
|
def execute
|
141
142
|
if not @match[1]
|
142
|
-
errmsg "\"disable\" must be followed \"display\", \"breakpoints\""
|
143
|
-
|
143
|
+
errmsg "\"disable\" must be followed by \"display\", \"breakpoints\" " \
|
144
|
+
"or breakpoint numbers.\n"
|
144
145
|
else
|
145
146
|
args = @match[1].split(/[ \t]+/)
|
146
147
|
param = args.shift
|
@@ -148,17 +149,17 @@ module Byebug
|
|
148
149
|
if subcmd
|
149
150
|
send("disable_#{subcmd.name}", args)
|
150
151
|
else
|
151
|
-
send(
|
152
|
+
send('disable_breakpoints', args.unshift(param))
|
152
153
|
end
|
153
154
|
end
|
154
155
|
end
|
155
156
|
|
156
157
|
def disable_breakpoints(args)
|
157
|
-
enable_disable_breakpoints(
|
158
|
+
enable_disable_breakpoints('Disable', args)
|
158
159
|
end
|
159
160
|
|
160
161
|
def disable_display(args)
|
161
|
-
enable_disable_display(
|
162
|
+
enable_disable_display('Disable', args)
|
162
163
|
end
|
163
164
|
|
164
165
|
class << self
|
@@ -173,7 +174,7 @@ module Byebug
|
|
173
174
|
return "Invalid \"disable\" subcommand \"#{args[1]}\"." unless subcmd
|
174
175
|
|
175
176
|
str = subcmd.short_help + '.'
|
176
|
-
str +=
|
177
|
+
str += '\n' + subcmd.long_help if subcmd.long_help
|
177
178
|
return str
|
178
179
|
end
|
179
180
|
|
data/lib/byebug/commands/eval.rb
CHANGED
@@ -31,11 +31,10 @@ module Byebug
|
|
31
31
|
%{
|
32
32
|
fin[ish] [frame-number]\tExecute until selected stack frame returns.
|
33
33
|
|
34
|
-
If no frame number is given, we run until the currently selected frame
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
returns.
|
34
|
+
If no frame number is given, we run until the currently selected frame returns.
|
35
|
+
The currently selected frame starts out the most-recent frame or 0 if no frame
|
36
|
+
positioning (e.g "up", "down" or "frame") has been performed. If a frame number
|
37
|
+
is given we run until that frame returns.
|
39
38
|
}
|
40
39
|
end
|
41
40
|
end
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -41,18 +41,18 @@ module Byebug
|
|
41
41
|
['locals', 2, 'Local variables of the current stack frame'],
|
42
42
|
['program', 2, 'Execution status of the program'],
|
43
43
|
['stack', 2, 'Backtrace of the stack'],
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
44
|
+
['thread', 6, 'List info about thread NUM',
|
45
|
+
'If no thread number is given, we list info for all threads. "terse"' \
|
46
|
+
' and "verbose" options are possible. If "terse", just give summary ' \
|
47
|
+
'thread name information. See "help info threads" for more detail ' \
|
48
|
+
'about this summary information. If "verbose" is appended to the end' \
|
49
|
+
' of the command, then the entire stack trace is given for each ' \
|
50
|
+
'thread.'],
|
51
|
+
['threads', 7, 'information of currently-known threads',
|
52
|
+
'This information includes whether the thread is the current thread ' \
|
53
|
+
'(+), it\'s suspended ($) or it\'s ignored (!), plus the thread ' \
|
54
|
+
'number and the top stack item. If "verbose" is given then the ' \
|
55
|
+
'entire stack frame is shown.'],
|
56
56
|
['variables', 1,
|
57
57
|
'Local and instance variables of the current stack frame']
|
58
58
|
].map do |name, min, short_help, long_help|
|
@@ -114,37 +114,30 @@ module Byebug
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def info_breakpoints(*args)
|
117
|
-
unless
|
118
|
-
|
119
|
-
|
117
|
+
return print "\"info breakpoints\" not available here.\n" unless
|
118
|
+
@state.context
|
119
|
+
|
120
|
+
return print "No breakpoints.\n" if Byebug.breakpoints.empty?
|
121
|
+
|
122
|
+
brkpts = Byebug.breakpoints.sort_by{|b| b.id}
|
123
|
+
unless args.empty?
|
124
|
+
indices = args.map{|a| a.to_i}
|
125
|
+
brkpts = brkpts.select{|b| indices.member?(b.id)}
|
126
|
+
return errmsg "No breakpoints found among list given.\n" if
|
127
|
+
brkpts.empty?
|
120
128
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
129
|
+
print "Num Enb What\n"
|
130
|
+
brkpts.each do |b|
|
131
|
+
print "%-3d %-3s at %s:%s%s\n", b.id,
|
132
|
+
b.enabled? ? 'y' : 'n',
|
133
|
+
b.source,
|
134
|
+
b.pos,
|
135
|
+
b.expr.nil? ? '' : " if #{b.expr}"
|
136
|
+
hits = b.hit_count
|
137
|
+
if hits > 0
|
138
|
+
s = (hits > 1) ? 's' : ''
|
139
|
+
print "\tbreakpoint already hit #{hits} time#{s}\n"
|
130
140
|
end
|
131
|
-
print "Num Enb What\n"
|
132
|
-
brkpts.each do |b|
|
133
|
-
if b.expr.nil?
|
134
|
-
print "%3d %s at %s:%s\n",
|
135
|
-
b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos
|
136
|
-
else
|
137
|
-
print "%3d %s at %s:%s if %s\n",
|
138
|
-
b.id, (b.enabled? ? 'y' : 'n'), b.source, b.pos, b.expr
|
139
|
-
end
|
140
|
-
hits = b.hit_count
|
141
|
-
if hits > 0
|
142
|
-
s = (hits > 1) ? 's' : ''
|
143
|
-
print "\tbreakpoint already hit #{hits} time#{s}\n"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
else
|
147
|
-
print "No breakpoints.\n"
|
148
141
|
end
|
149
142
|
end
|
150
143
|
|
@@ -167,6 +160,35 @@ module Byebug
|
|
167
160
|
end
|
168
161
|
end
|
169
162
|
|
163
|
+
def info_file_path(file)
|
164
|
+
path = LineCache.path(file)
|
165
|
+
if path != file
|
166
|
+
print " - #{path}"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def info_file_lines(file)
|
171
|
+
lines = LineCache.size(file)
|
172
|
+
print "\t %d lines\n", lines if lines
|
173
|
+
end
|
174
|
+
|
175
|
+
def info_file_breakpoints(file)
|
176
|
+
breakpoints = LineCache.trace_line_numbers(file)
|
177
|
+
if breakpoints
|
178
|
+
print "\tbreakpoint line numbers:\n"
|
179
|
+
print columnize(breakpoints.to_a.sort, self.class.settings[:width])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def info_file_mtime(file)
|
184
|
+
stat = LineCache.stat(file)
|
185
|
+
print "\t%s\n", stat.mtime if stat
|
186
|
+
end
|
187
|
+
|
188
|
+
def info_file_sha1(file)
|
189
|
+
print "\t%s\n", LineCache.sha1(file)
|
190
|
+
end
|
191
|
+
|
170
192
|
def info_file(*args)
|
171
193
|
return info_files unless args[0]
|
172
194
|
file = args[0]
|
@@ -184,33 +206,13 @@ module Byebug
|
|
184
206
|
end
|
185
207
|
|
186
208
|
print "File #{file}"
|
187
|
-
|
188
|
-
if %w(all basic path).member?(subcmd.name) and path != file
|
189
|
-
print " - #{path}"
|
190
|
-
end
|
209
|
+
info_file_path(file) if %w(all basic path).member?(subcmd.name)
|
191
210
|
print "\n"
|
192
211
|
|
193
|
-
if %w(all basic lines).member?(subcmd.name)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
if %w(all breakpoints).member?(subcmd.name)
|
199
|
-
breakpoints = LineCache.trace_line_numbers(file)
|
200
|
-
if breakpoints
|
201
|
-
print "\tbreakpoint line numbers:\n"
|
202
|
-
print columnize(breakpoints.to_a.sort, self.class.settings[:width])
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
if %w(all mtime).member?(subcmd.name)
|
207
|
-
stat = LineCache.stat(file)
|
208
|
-
print "\t%s\n", stat.mtime if stat
|
209
|
-
end
|
210
|
-
|
211
|
-
if %w(all sha1).member?(subcmd.name)
|
212
|
-
print "\t%s\n", LineCache.sha1(file)
|
213
|
-
end
|
212
|
+
info_file_lines(file) if %w(all basic lines).member?(subcmd.name)
|
213
|
+
info_file_breakpoints(file) if %w(all breakpoints).member?(subcmd.name)
|
214
|
+
info_file_mtime(file) if %w(all mtime).member?(subcmd.name)
|
215
|
+
info_file_sha1(file) if %w(all sha1).member?(subcmd.name)
|
214
216
|
end
|
215
217
|
|
216
218
|
def info_files(*args)
|
@@ -301,56 +303,56 @@ module Byebug
|
|
301
303
|
print_backtrace
|
302
304
|
end
|
303
305
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
306
|
+
def info_thread_preamble(arg)
|
307
|
+
if not @state.context
|
308
|
+
errmsg "info threads not available here.\n"
|
309
|
+
return false, false
|
310
|
+
end
|
311
|
+
verbose = if arg
|
312
|
+
subcmd = find(InfoThreadSubcommands, arg)
|
313
|
+
unless subcmd
|
314
|
+
errmsg "'terse' or 'verbose' expected. Got '#{arg}'\n"
|
315
|
+
return false, false
|
316
|
+
end
|
317
|
+
'verbose' == subcmd.name
|
318
|
+
else
|
319
|
+
false
|
320
|
+
end
|
321
|
+
return true, verbose
|
322
|
+
end
|
323
|
+
private :info_thread_preamble
|
324
|
+
|
325
|
+
def info_threads(*args)
|
326
|
+
ok, verbose = info_thread_preamble(args[0])
|
327
|
+
return unless ok
|
328
|
+
threads = Byebug.contexts.sort_by{|c| c.thnum}.each do |c|
|
329
|
+
display_context(c, !verbose)
|
330
|
+
if verbose and not c.ignored?
|
331
|
+
(0...c.stack_size).each do |idx|
|
332
|
+
print "\t"
|
333
|
+
print_frame(idx, false, c)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def info_thread(*args)
|
340
|
+
unless args[0]
|
341
|
+
info_threads(args[0])
|
342
|
+
return
|
343
|
+
end
|
344
|
+
ok, verbose = info_thread_preamble(args[1])
|
345
|
+
return unless ok
|
346
|
+
c = parse_thread_num("info thread" , args[0])
|
347
|
+
return unless c
|
348
|
+
display_context(c, !verbose)
|
349
|
+
if verbose and not c.ignored?
|
350
|
+
(0...c.stack_size).each do |idx|
|
351
|
+
print "\t"
|
352
|
+
print_frame(idx, false, c)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
354
356
|
|
355
357
|
def info_global_variables(*args)
|
356
358
|
unless @state.context
|