byebug 0.0.1
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.
- data/.gitignore +10 -0
- data/.travis.yml +8 -0
- data/AUTHORS +10 -0
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +5 -0
- data/Rakefile +28 -0
- data/bin/byebug +395 -0
- data/byebug.gemspec +29 -0
- data/doc/hanoi.rb +35 -0
- data/doc/primes.rb +28 -0
- data/doc/rdebug-emacs.texi +1030 -0
- data/doc/test-tri2.rb +18 -0
- data/doc/tri3.rb +8 -0
- data/doc/triangle.rb +12 -0
- data/ext/byebug/breakpoint.c +476 -0
- data/ext/byebug/byebug.c +512 -0
- data/ext/byebug/byebug.h +131 -0
- data/ext/byebug/context.c +424 -0
- data/ext/byebug/extconf.rb +21 -0
- data/ext/byebug/locker.c +53 -0
- data/lib/byebug.rb +404 -0
- data/lib/byebug/command.rb +232 -0
- data/lib/byebug/commands/breakpoints.rb +153 -0
- data/lib/byebug/commands/catchpoint.rb +56 -0
- data/lib/byebug/commands/condition.rb +49 -0
- data/lib/byebug/commands/continue.rb +38 -0
- data/lib/byebug/commands/control.rb +110 -0
- data/lib/byebug/commands/display.rb +122 -0
- data/lib/byebug/commands/edit.rb +48 -0
- data/lib/byebug/commands/enable.rb +202 -0
- data/lib/byebug/commands/eval.rb +176 -0
- data/lib/byebug/commands/finish.rb +43 -0
- data/lib/byebug/commands/frame.rb +303 -0
- data/lib/byebug/commands/help.rb +56 -0
- data/lib/byebug/commands/info.rb +462 -0
- data/lib/byebug/commands/irb.rb +123 -0
- data/lib/byebug/commands/jump.rb +66 -0
- data/lib/byebug/commands/kill.rb +51 -0
- data/lib/byebug/commands/list.rb +94 -0
- data/lib/byebug/commands/method.rb +84 -0
- data/lib/byebug/commands/quit.rb +39 -0
- data/lib/byebug/commands/reload.rb +40 -0
- data/lib/byebug/commands/save.rb +90 -0
- data/lib/byebug/commands/set.rb +210 -0
- data/lib/byebug/commands/show.rb +246 -0
- data/lib/byebug/commands/skip.rb +35 -0
- data/lib/byebug/commands/source.rb +36 -0
- data/lib/byebug/commands/stepping.rb +83 -0
- data/lib/byebug/commands/threads.rb +189 -0
- data/lib/byebug/commands/tmate.rb +36 -0
- data/lib/byebug/commands/trace.rb +56 -0
- data/lib/byebug/commands/variables.rb +199 -0
- data/lib/byebug/context.rb +58 -0
- data/lib/byebug/helper.rb +69 -0
- data/lib/byebug/interface.rb +223 -0
- data/lib/byebug/processor.rb +468 -0
- data/lib/byebug/version.rb +3 -0
- data/man/rdebug.1 +241 -0
- data/test/breakpoints_test.rb +357 -0
- data/test/conditions_test.rb +77 -0
- data/test/continue_test.rb +44 -0
- data/test/display_test.rb +141 -0
- data/test/edit_test.rb +56 -0
- data/test/eval_test.rb +92 -0
- data/test/examples/breakpoint1.rb +15 -0
- data/test/examples/breakpoint2.rb +7 -0
- data/test/examples/conditions.rb +4 -0
- data/test/examples/continue.rb +4 -0
- data/test/examples/display.rb +5 -0
- data/test/examples/edit.rb +3 -0
- data/test/examples/edit2.rb +3 -0
- data/test/examples/eval.rb +4 -0
- data/test/examples/finish.rb +20 -0
- data/test/examples/frame.rb +20 -0
- data/test/examples/frame_threads.rb +31 -0
- data/test/examples/help.rb +2 -0
- data/test/examples/info.rb +38 -0
- data/test/examples/info2.rb +3 -0
- data/test/examples/info_threads.rb +48 -0
- data/test/examples/irb.rb +6 -0
- data/test/examples/jump.rb +14 -0
- data/test/examples/kill.rb +2 -0
- data/test/examples/list.rb +12 -0
- data/test/examples/method.rb +15 -0
- data/test/examples/post_mortem.rb +19 -0
- data/test/examples/quit.rb +2 -0
- data/test/examples/reload.rb +6 -0
- data/test/examples/restart.rb +6 -0
- data/test/examples/save.rb +3 -0
- data/test/examples/set.rb +3 -0
- data/test/examples/set_annotate.rb +12 -0
- data/test/examples/settings.rb +1 -0
- data/test/examples/show.rb +2 -0
- data/test/examples/source.rb +3 -0
- data/test/examples/stepping.rb +21 -0
- data/test/examples/thread.rb +32 -0
- data/test/examples/tmate.rb +10 -0
- data/test/examples/trace.rb +7 -0
- data/test/examples/trace_threads.rb +20 -0
- data/test/examples/variables.rb +26 -0
- data/test/finish_test.rb +48 -0
- data/test/frame_test.rb +143 -0
- data/test/help_test.rb +50 -0
- data/test/info_test.rb +313 -0
- data/test/irb_test.rb +81 -0
- data/test/jump_test.rb +70 -0
- data/test/kill_test.rb +48 -0
- data/test/list_test.rb +145 -0
- data/test/method_test.rb +70 -0
- data/test/post_mortem_test.rb +27 -0
- data/test/quit_test.rb +56 -0
- data/test/reload_test.rb +44 -0
- data/test/restart_test.rb +164 -0
- data/test/save_test.rb +92 -0
- data/test/set_test.rb +177 -0
- data/test/show_test.rb +293 -0
- data/test/source_test.rb +45 -0
- data/test/stepping_test.rb +130 -0
- data/test/support/breakpoint.rb +13 -0
- data/test/support/context.rb +14 -0
- data/test/support/matchers.rb +67 -0
- data/test/support/mocha_extensions.rb +72 -0
- data/test/support/processor.rb +7 -0
- data/test/support/test_dsl.rb +206 -0
- data/test/support/test_interface.rb +68 -0
- data/test/test_helper.rb +10 -0
- data/test/tmate_test.rb +44 -0
- data/test/trace_test.rb +159 -0
- data/test/variables_test.rb +119 -0
- metadata +265 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
module Byebug
|
2
|
+
|
3
|
+
# Implements byebug "skip" command
|
4
|
+
class SkipCommand < Command
|
5
|
+
self.allow_in_control = true
|
6
|
+
|
7
|
+
def regexp
|
8
|
+
/ ^\s*
|
9
|
+
sk(?:ip)? \s*
|
10
|
+
$
|
11
|
+
/ix
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
Byebug::skip_next_exception
|
16
|
+
print "ok\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def help_command
|
21
|
+
%w[skip]
|
22
|
+
end
|
23
|
+
|
24
|
+
def help(cmd)
|
25
|
+
%{
|
26
|
+
sk[ip]\tskip the next thrown exception
|
27
|
+
|
28
|
+
This is useful if you've explicitly caught an exception through
|
29
|
+
the "catch" command, and wish to pass the exception on to the
|
30
|
+
code that you're debugging.
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Byebug
|
2
|
+
# Implements byebug "source" command.
|
3
|
+
class SourceCommand < Command
|
4
|
+
self.allow_in_control = true
|
5
|
+
|
6
|
+
def regexp
|
7
|
+
/^\s* so(?:urce)? \s+ (.+) $/x
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
file = File.expand_path(@match[1]).strip
|
12
|
+
unless File.exist?(file)
|
13
|
+
errmsg "Command file '#{file}' is not found\n"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
if @state and @state.interface
|
17
|
+
@state.interface.command_queue += File.open(file).readlines
|
18
|
+
else
|
19
|
+
Byebug.run_script(file, @state)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def help_command
|
25
|
+
'source'
|
26
|
+
end
|
27
|
+
|
28
|
+
def help(cmd)
|
29
|
+
%{
|
30
|
+
source FILE\texecutes a file containing byebug commands
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Byebug
|
2
|
+
|
3
|
+
# Mix-in module to assist in command parsing.
|
4
|
+
module SteppingFunctions # :nodoc:
|
5
|
+
def parse_stepping_args(command_name, match)
|
6
|
+
if match[1].nil?
|
7
|
+
force = Command.settings[:force_stepping]
|
8
|
+
elsif match[1] == '+'
|
9
|
+
force = true
|
10
|
+
elsif match[1] == '-'
|
11
|
+
force = false
|
12
|
+
end
|
13
|
+
steps = get_int(match[2], command_name, 1)
|
14
|
+
return [steps, force]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Implements byebug "next" command.
|
19
|
+
class NextCommand < Command
|
20
|
+
self.allow_in_post_mortem = false
|
21
|
+
self.need_context = true
|
22
|
+
|
23
|
+
def regexp
|
24
|
+
/^\s* n(?:ext)?
|
25
|
+
([+-])?(?:\s+(\S+))?
|
26
|
+
\s*$/x
|
27
|
+
end
|
28
|
+
|
29
|
+
def execute
|
30
|
+
steps, force = parse_stepping_args("Next", @match)
|
31
|
+
return unless steps
|
32
|
+
@state.context.step_over steps, @state.frame_pos, force
|
33
|
+
@state.proceed
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def help_command
|
38
|
+
'next'
|
39
|
+
end
|
40
|
+
|
41
|
+
def help(cmd)
|
42
|
+
%{
|
43
|
+
n[ext][+-]?[ nnn]\tstep over once or nnn times,
|
44
|
+
\t\t'+' forces to move to another line.
|
45
|
+
\t\t'-' is the opposite of '+' and disables the force_stepping setting.
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Implements byebug "step" command.
|
52
|
+
class StepCommand < Command
|
53
|
+
self.allow_in_post_mortem = false
|
54
|
+
self.need_context = true
|
55
|
+
|
56
|
+
def regexp
|
57
|
+
/^\s* s(?:tep)?
|
58
|
+
([+-])?(?:\s+(\S+))?
|
59
|
+
\s*$/x
|
60
|
+
end
|
61
|
+
|
62
|
+
def execute
|
63
|
+
steps, force = parse_stepping_args("Step", @match)
|
64
|
+
return unless steps
|
65
|
+
@state.context.step(steps, force)
|
66
|
+
@state.proceed
|
67
|
+
end
|
68
|
+
|
69
|
+
class << self
|
70
|
+
def help_command
|
71
|
+
'step'
|
72
|
+
end
|
73
|
+
|
74
|
+
def help(cmd)
|
75
|
+
%{
|
76
|
+
s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times
|
77
|
+
\t\t'+' forces to move to another line.
|
78
|
+
\t\t'-' is the opposite of '+' and disables the force_stepping setting.
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Byebug
|
2
|
+
module ThreadFunctions # :nodoc:
|
3
|
+
def display_context(c, show_top_frame=true)
|
4
|
+
c_flag = c.thread == Thread.current ? '+' : ' '
|
5
|
+
c_flag = '$' if c.suspended?
|
6
|
+
d_flag = c.ignored? ? '!' : ' '
|
7
|
+
print "%s%s", c_flag, d_flag
|
8
|
+
print "%d ", c.thnum
|
9
|
+
print "%s\t", c.thread.inspect
|
10
|
+
if c.stack_size > 0 and show_top_frame
|
11
|
+
print "%s:%d", c.frame_file(0), c.frame_line(0)
|
12
|
+
end
|
13
|
+
print "\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_thread_num(subcmd, arg)
|
17
|
+
if '' == arg
|
18
|
+
errmsg "'%s' needs a thread number\n" % subcmd
|
19
|
+
nil
|
20
|
+
else
|
21
|
+
thread_num = get_int(arg, "thread #{subcmd}", 1)
|
22
|
+
return nil unless thread_num
|
23
|
+
get_context(thread_num)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_thread_num_for_cmd(subcmd, arg)
|
28
|
+
c = parse_thread_num(subcmd, arg)
|
29
|
+
return nil unless c
|
30
|
+
case
|
31
|
+
when nil == c
|
32
|
+
errmsg "No such thread.\n"
|
33
|
+
when @state.context == c
|
34
|
+
errmsg "It's the current thread.\n"
|
35
|
+
when c.ignored?
|
36
|
+
errmsg "Can't #{subcmd} to the byebug thread #{arg}.\n"
|
37
|
+
else # Everything is okay
|
38
|
+
return c
|
39
|
+
end
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ThreadListCommand < Command # :nodoc:
|
45
|
+
self.allow_in_control = true
|
46
|
+
|
47
|
+
def regexp
|
48
|
+
/^\s*th(?:read)?\s+l(?:ist)?\s*$/
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute
|
52
|
+
threads = Byebug.contexts.sort_by{|c| c.thnum}.each do |c|
|
53
|
+
display_context(c)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class << self
|
58
|
+
def help_command
|
59
|
+
'thread'
|
60
|
+
end
|
61
|
+
|
62
|
+
def help(cmd)
|
63
|
+
%{
|
64
|
+
th[read] l[ist]\t\t\tlist all threads
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class ThreadStopCommand < Command # :nodoc:
|
71
|
+
self.allow_in_control = true
|
72
|
+
self.allow_in_post_mortem = false
|
73
|
+
self.need_context = true
|
74
|
+
|
75
|
+
def regexp
|
76
|
+
/^\s*th(?:read)?\s+stop\s*(\S*)\s*$/
|
77
|
+
end
|
78
|
+
|
79
|
+
def execute
|
80
|
+
c = parse_thread_num_for_cmd("thread stop", @match[1])
|
81
|
+
return unless c
|
82
|
+
c.suspend
|
83
|
+
display_context(c)
|
84
|
+
end
|
85
|
+
|
86
|
+
class << self
|
87
|
+
def help_command
|
88
|
+
'thread'
|
89
|
+
end
|
90
|
+
|
91
|
+
def help(cmd)
|
92
|
+
%{
|
93
|
+
th[read] stop <nnn>\t\tstop thread nnn
|
94
|
+
}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class ThreadResumeCommand < Command # :nodoc:
|
100
|
+
self.allow_in_post_mortem = false
|
101
|
+
self.allow_in_control = true
|
102
|
+
self.need_context = true
|
103
|
+
|
104
|
+
def regexp
|
105
|
+
/^\s*th(?:read)?\s+resume\s*(\S*)\s*$/
|
106
|
+
end
|
107
|
+
|
108
|
+
def execute
|
109
|
+
c = parse_thread_num_for_cmd("thread resume", @match[1])
|
110
|
+
return unless c
|
111
|
+
if !c.thread.stop?
|
112
|
+
print "Already running."
|
113
|
+
return
|
114
|
+
end
|
115
|
+
c.resume
|
116
|
+
display_context(c)
|
117
|
+
end
|
118
|
+
|
119
|
+
class << self
|
120
|
+
def help_command
|
121
|
+
'thread'
|
122
|
+
end
|
123
|
+
|
124
|
+
def help(cmd)
|
125
|
+
%{
|
126
|
+
th[read] resume <nnn>\t\tresume thread nnn
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Thread switch Must come after "Thread resume" because "switch" is
|
133
|
+
# optional
|
134
|
+
|
135
|
+
class ThreadSwitchCommand < Command # :nodoc:
|
136
|
+
self.allow_in_control = true
|
137
|
+
self.allow_in_post_mortem = false
|
138
|
+
self.need_context = true
|
139
|
+
|
140
|
+
def regexp
|
141
|
+
/^\s*th(?:read)?\s*(?:sw(?:itch)?)?\s+(\S+)\s*$/
|
142
|
+
end
|
143
|
+
|
144
|
+
def execute
|
145
|
+
c = parse_thread_num_for_cmd("thread switch", @match[1])
|
146
|
+
return unless c
|
147
|
+
display_context(c)
|
148
|
+
c.stop_next = 1
|
149
|
+
c.thread.run
|
150
|
+
@state.proceed
|
151
|
+
end
|
152
|
+
|
153
|
+
class << self
|
154
|
+
def help_command
|
155
|
+
'thread'
|
156
|
+
end
|
157
|
+
|
158
|
+
def help(cmd)
|
159
|
+
%{
|
160
|
+
th[read] [sw[itch]] <nnn>\tswitch thread context to nnn
|
161
|
+
}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class ThreadCurrentCommand < Command # :nodoc:
|
167
|
+
self.need_context = true
|
168
|
+
|
169
|
+
def regexp
|
170
|
+
/^\s*th(?:read)?\s*(?:cur(?:rent)?)?\s*$/
|
171
|
+
end
|
172
|
+
|
173
|
+
def execute
|
174
|
+
display_context(@state.context)
|
175
|
+
end
|
176
|
+
|
177
|
+
class << self
|
178
|
+
def help_command
|
179
|
+
'thread'
|
180
|
+
end
|
181
|
+
|
182
|
+
def help(cmd)
|
183
|
+
%{
|
184
|
+
th[read] [cur[rent]]\t\tshow current thread
|
185
|
+
}
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Byebug
|
2
|
+
if RUBY_PLATFORM =~ /darwin/
|
3
|
+
class TextMateCommand < Command # :nodoc:
|
4
|
+
def regexp
|
5
|
+
/^\s*tm(?:ate)?(?:\s*(\d+))?$/
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
if @match[1]
|
10
|
+
frm_n = @match[1].to_i
|
11
|
+
if frm_n > @state.context.stack_size || frm_n == 0
|
12
|
+
print "Wrong frame number\n"
|
13
|
+
return
|
14
|
+
end
|
15
|
+
file, line = @state.context.frame_file(frm_n-1), @state.context.frame_line(frm_n-1)
|
16
|
+
else
|
17
|
+
file, line = @state.file, @state.line
|
18
|
+
end
|
19
|
+
%x|open 'txmt://open?url=file://#{File.expand_path(file)}&line=#{line}'|
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def help_command
|
24
|
+
'tmate'
|
25
|
+
end
|
26
|
+
|
27
|
+
def help(cmd)
|
28
|
+
%{
|
29
|
+
tm[ate] n\topens a current file in TextMate.
|
30
|
+
\t\tIt uses n-th frame if arg (n) is specifed.
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Byebug
|
2
|
+
class TraceCommand < Command # :nodoc:
|
3
|
+
def regexp
|
4
|
+
/^\s* tr(?:ace)? (?: \s+ (\S+)) # on |off | var(iable)
|
5
|
+
(?: \s+ (\S+))? # (all | variable-name)?
|
6
|
+
(?: \s+ (\S+))? \s* # (stop | nostop)?
|
7
|
+
$/ix
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
if @match[1] =~ /on|off/
|
12
|
+
onoff = 'on' == @match[1]
|
13
|
+
if @match[2]
|
14
|
+
Byebug.tracing = onoff
|
15
|
+
print "Tracing %s all threads.\n" % (onoff ? 'on' : 'off')
|
16
|
+
else
|
17
|
+
Byebug.current_context.tracing = onoff
|
18
|
+
print "Tracing %s on current thread.\n" % (onoff ? 'on' : 'off')
|
19
|
+
end
|
20
|
+
elsif @match[1] =~ /var(?:iable)?/
|
21
|
+
varname=@match[2]
|
22
|
+
if debug_eval("defined?(#{varname})")
|
23
|
+
if @match[3] && @match[3] !~ /(:?no)?stop/
|
24
|
+
errmsg("expecting 'stop' or 'nostop'; got %s\n" % @match[3])
|
25
|
+
else
|
26
|
+
dbg_cmd = (@match[3] && (@match[3] !~ /nostop/)) ? 'byebug' : ''
|
27
|
+
end
|
28
|
+
eval("
|
29
|
+
trace_var(:#{varname}) do |val|
|
30
|
+
print \"traced variable #{varname} has value \#{val}\n\"
|
31
|
+
#{dbg_cmd}
|
32
|
+
end")
|
33
|
+
else
|
34
|
+
errmsg "#{varname} is not a global variable.\n"
|
35
|
+
end
|
36
|
+
else
|
37
|
+
errmsg("expecting 'on', 'off', 'var' or 'variable'; got: %s\n" %
|
38
|
+
@match[1])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class << self
|
43
|
+
def help_command
|
44
|
+
'trace'
|
45
|
+
end
|
46
|
+
|
47
|
+
def help(cmd)
|
48
|
+
%{
|
49
|
+
tr[ace] (on|off)\tset trace mode of current thread
|
50
|
+
tr[ace] (on|off) all\tset trace mode of all threads
|
51
|
+
tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
module Byebug
|
2
|
+
module VarFunctions # :nodoc:
|
3
|
+
def var_list(ary, b = get_binding)
|
4
|
+
ary.sort!
|
5
|
+
for v in ary
|
6
|
+
begin
|
7
|
+
s = debug_eval(v.to_s, b).inspect
|
8
|
+
rescue
|
9
|
+
begin
|
10
|
+
s = debug_eval(v.to_s, b).to_s
|
11
|
+
rescue
|
12
|
+
s = "*Error in evaluation*"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
if s.size > self.class.settings[:width]
|
16
|
+
s[self.class.settings[:width]-3 .. -1] = "..."
|
17
|
+
end
|
18
|
+
print "%s = %s\n", v, s
|
19
|
+
end
|
20
|
+
end
|
21
|
+
def var_class_self
|
22
|
+
obj = debug_eval('self')
|
23
|
+
var_list(obj.class.class_variables, get_binding)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Implements the byebug 'var class' command.
|
28
|
+
class VarClassVarCommand < Command
|
29
|
+
def regexp
|
30
|
+
/^\s*v(?:ar)?\s+cl(?:ass)?/
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
unless @state.context
|
35
|
+
errmsg "can't get class variables here.\n"
|
36
|
+
return
|
37
|
+
end
|
38
|
+
var_class_self
|
39
|
+
end
|
40
|
+
|
41
|
+
class << self
|
42
|
+
def help_command
|
43
|
+
'var'
|
44
|
+
end
|
45
|
+
|
46
|
+
def help(cmd)
|
47
|
+
%{
|
48
|
+
v[ar] cl[ass] \t\t\tshow class variables of self
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class VarConstantCommand < Command # :nodoc:
|
55
|
+
def regexp
|
56
|
+
/^\s*v(?:ar)?\s+co(?:nst(?:ant)?)?\s+/
|
57
|
+
end
|
58
|
+
|
59
|
+
def execute
|
60
|
+
obj = debug_eval(@match.post_match)
|
61
|
+
if obj.kind_of? Module
|
62
|
+
constants = debug_eval("#{@match.post_match}.constants")
|
63
|
+
constants.sort!
|
64
|
+
for c in constants
|
65
|
+
next if c =~ /SCRIPT/
|
66
|
+
value = obj.const_get(c) rescue "ERROR: #{$!}"
|
67
|
+
print " %s => %p\n", c, value
|
68
|
+
end
|
69
|
+
else
|
70
|
+
print "Should be Class/Module: %s\n", @match.post_match
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class << self
|
75
|
+
def help_command
|
76
|
+
'var'
|
77
|
+
end
|
78
|
+
|
79
|
+
def help(cmd)
|
80
|
+
%{
|
81
|
+
v[ar] co[nst] <object>\t\tshow constants of object
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class VarGlobalCommand < Command # :nodoc:
|
88
|
+
def regexp
|
89
|
+
/^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
|
90
|
+
end
|
91
|
+
|
92
|
+
def execute
|
93
|
+
var_list(global_variables)
|
94
|
+
end
|
95
|
+
|
96
|
+
class << self
|
97
|
+
def help_command
|
98
|
+
'var'
|
99
|
+
end
|
100
|
+
|
101
|
+
def help(cmd)
|
102
|
+
%{
|
103
|
+
v[ar] g[lobal]\t\t\tshow global variables
|
104
|
+
}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class VarInstanceCommand < Command # :nodoc:
|
110
|
+
def regexp
|
111
|
+
/^\s*v(?:ar)?\s+ins(?:tance)?\s*/
|
112
|
+
end
|
113
|
+
|
114
|
+
def execute
|
115
|
+
obj = debug_eval(@match.post_match.empty? ? 'self' : @match.post_match)
|
116
|
+
var_list(obj.instance_variables, obj.instance_eval{binding()})
|
117
|
+
end
|
118
|
+
|
119
|
+
class << self
|
120
|
+
def help_command
|
121
|
+
'var'
|
122
|
+
end
|
123
|
+
|
124
|
+
def help(cmd)
|
125
|
+
%{
|
126
|
+
v[ar] i[nstance] <object>\tshow instance variables of object
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Implements the byebug 'var local' command.
|
133
|
+
class VarLocalCommand < Command
|
134
|
+
def regexp
|
135
|
+
/^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
|
136
|
+
end
|
137
|
+
|
138
|
+
def execute
|
139
|
+
locals = @state.context.frame_locals(@state.frame_pos)
|
140
|
+
_self = @state.context.frame_self(@state.frame_pos)
|
141
|
+
locals.keys.sort.each do |name|
|
142
|
+
print " %s => %p\n", name, locals[name]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class << self
|
147
|
+
def help_command
|
148
|
+
'var'
|
149
|
+
end
|
150
|
+
|
151
|
+
def help(cmd)
|
152
|
+
%{
|
153
|
+
v[ar] l[ocal]\t\t\tshow local variables
|
154
|
+
}
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Implements the byebug 'var inherit' command.
|
160
|
+
begin
|
161
|
+
require 'classtree'
|
162
|
+
have_classtree = true
|
163
|
+
rescue LoadError
|
164
|
+
have_classtree = false
|
165
|
+
end
|
166
|
+
|
167
|
+
class VarInheritCommand < Command
|
168
|
+
def regexp
|
169
|
+
/^\s*v(?:ar)?\s+ct\s*/
|
170
|
+
end
|
171
|
+
|
172
|
+
def execute
|
173
|
+
unless @state.context
|
174
|
+
errmsg "can't get object inheritance.\n"
|
175
|
+
return
|
176
|
+
end
|
177
|
+
puts @match.post_match
|
178
|
+
obj = debug_eval("#{@match.post_match}.classtree")
|
179
|
+
if obj
|
180
|
+
print obj
|
181
|
+
else
|
182
|
+
errmsg "Trouble getting object #{@match.post_match}\n"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
class << self
|
187
|
+
def help_command
|
188
|
+
'var'
|
189
|
+
end
|
190
|
+
|
191
|
+
def help(cmd)
|
192
|
+
%{
|
193
|
+
v[ar] ct\t\t\tshow class heirarchy of object
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end if have_classtree
|
198
|
+
|
199
|
+
end
|