byebug 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +4 -0
  2. data/.travis.yml +0 -5
  3. data/CHANGELOG.md +6 -0
  4. data/Gemfile +1 -1
  5. data/LICENSE +23 -20
  6. data/byebug.gemspec +5 -5
  7. data/ext/byebug/breakpoint.c +102 -134
  8. data/ext/byebug/byebug.c +110 -64
  9. data/ext/byebug/byebug.h +2 -3
  10. data/ext/byebug/context.c +72 -39
  11. data/lib/byebug.rb +34 -38
  12. data/lib/byebug/command.rb +19 -24
  13. data/lib/byebug/commands/breakpoints.rb +11 -12
  14. data/lib/byebug/commands/catchpoint.rb +1 -1
  15. data/lib/byebug/commands/control.rb +2 -4
  16. data/lib/byebug/commands/finish.rb +1 -1
  17. data/lib/byebug/commands/frame.rb +15 -17
  18. data/lib/byebug/commands/info.rb +29 -28
  19. data/lib/byebug/commands/irb.rb +23 -21
  20. data/lib/byebug/commands/method.rb +4 -4
  21. data/lib/byebug/commands/reload.rb +8 -6
  22. data/lib/byebug/commands/set.rb +27 -23
  23. data/lib/byebug/commands/show.rb +6 -4
  24. data/lib/byebug/commands/stepping.rb +2 -2
  25. data/lib/byebug/commands/threads.rb +10 -10
  26. data/lib/byebug/commands/trace.rb +13 -14
  27. data/lib/byebug/commands/variables.rb +14 -12
  28. data/lib/byebug/context.rb +2 -15
  29. data/lib/byebug/interface.rb +5 -0
  30. data/lib/byebug/processor.rb +59 -64
  31. data/lib/byebug/version.rb +2 -1
  32. data/old_doc/Makefile +20 -0
  33. data/{man/rdebug.1 → old_doc/byebug.1} +5 -5
  34. data/old_doc/byebug.html +6178 -0
  35. data/old_doc/byebug.texi +3775 -0
  36. data/{doc → old_doc}/hanoi.rb +0 -0
  37. data/{doc → old_doc}/primes.rb +0 -0
  38. data/{doc → old_doc}/test-tri2.rb +0 -0
  39. data/{doc → old_doc}/tri3.rb +0 -0
  40. data/{doc → old_doc}/triangle.rb +0 -0
  41. data/test/breakpoints_test.rb +96 -60
  42. data/test/conditions_test.rb +15 -12
  43. data/test/examples/info.rb +5 -5
  44. data/test/examples/stepping.rb +1 -1
  45. data/test/frame_test.rb +40 -39
  46. data/test/info_test.rb +105 -96
  47. data/test/irb_test.rb +66 -61
  48. data/test/jump_test.rb +18 -9
  49. data/test/list_test.rb +114 -107
  50. data/test/restart_test.rb +51 -58
  51. data/test/save_test.rb +8 -7
  52. data/test/set_test.rb +8 -11
  53. data/test/show_test.rb +3 -5
  54. data/test/stepping_test.rb +43 -53
  55. data/test/support/context.rb +1 -0
  56. data/test/support/processor.rb +10 -4
  57. data/test/support/test_dsl.rb +46 -18
  58. data/test/support/test_interface.rb +8 -5
  59. data/test/test_helper.rb +2 -2
  60. data/test/trace_test.rb +123 -124
  61. metadata +39 -17
  62. data/AUTHORS +0 -10
  63. data/doc/rdebug-emacs.texi +0 -1030
@@ -1,6 +1,8 @@
1
1
  module Byebug
2
+
2
3
  # Mix-in module to showing settings
3
- module ShowFunctions # :nodoc:
4
+ module ShowFunctions
5
+
4
6
  def show_setting(setting_name)
5
7
  case setting_name
6
8
  when /^annotate$/
@@ -73,7 +75,7 @@ module Byebug
73
75
  return s
74
76
  when /^byebugtesting$/
75
77
  on_off = Command.settings[:byebugtesting]
76
- return "Currently testing the byebug is #{show_onoff(on_off)}."
78
+ return "Currently testing byebug is #{show_onoff(on_off)}."
77
79
  when /^forcestep$/
78
80
  on_off = self.class.settings[:force_stepping]
79
81
  return "force-stepping is #{show_onoff(on_off)}."
@@ -116,7 +118,7 @@ module Byebug
116
118
  end
117
119
  return s.join("\n")
118
120
  when /^linetrace$/
119
- on_off = Command.settings[:tracing]
121
+ on_off = Byebug.tracing
120
122
  return "line tracing is #{show_onoff(on_off)}."
121
123
  when /^linetrace\+$/
122
124
  on_off = Command.settings[:tracing_plus]
@@ -230,7 +232,7 @@ show history size -- Show the size of the command history"],
230
232
  end
231
233
  end
232
234
  s = "
233
- Generic command for showing things about the byebug.
235
+ Generic command for showing things about byebug.
234
236
 
235
237
  --
236
238
  List of show subcommands:
@@ -1,7 +1,7 @@
1
1
  module Byebug
2
2
 
3
3
  # Mix-in module to assist in command parsing.
4
- module SteppingFunctions # :nodoc:
4
+ module SteppingFunctions
5
5
  def parse_stepping_args(command_name, match)
6
6
  if match[1].nil?
7
7
  force = Command.settings[:force_stepping]
@@ -62,7 +62,7 @@ module Byebug
62
62
  def execute
63
63
  steps, force = parse_stepping_args("Step", @match)
64
64
  return unless steps
65
- @state.context.step(steps, force)
65
+ @state.context.step steps, force
66
66
  @state.proceed
67
67
  end
68
68
 
@@ -12,7 +12,7 @@ module Byebug
12
12
  end
13
13
  print "\n"
14
14
  end
15
-
15
+
16
16
  def parse_thread_num(subcmd, arg)
17
17
  if '' == arg
18
18
  errmsg "'%s' needs a thread number\n" % subcmd
@@ -27,13 +27,13 @@ module Byebug
27
27
  def parse_thread_num_for_cmd(subcmd, arg)
28
28
  c = parse_thread_num(subcmd, arg)
29
29
  return nil unless c
30
- case
30
+ case
31
31
  when nil == c
32
32
  errmsg "No such thread.\n"
33
33
  when @state.context == c
34
34
  errmsg "It's the current thread.\n"
35
35
  when c.ignored?
36
- errmsg "Can't #{subcmd} to the byebug thread #{arg}.\n"
36
+ errmsg "Can't #{subcmd} to byebug's thread #{arg}.\n"
37
37
  else # Everything is okay
38
38
  return c
39
39
  end
@@ -71,14 +71,14 @@ module Byebug
71
71
  self.allow_in_control = true
72
72
  self.allow_in_post_mortem = false
73
73
  self.need_context = true
74
-
74
+
75
75
  def regexp
76
76
  /^\s*th(?:read)?\s+stop\s*(\S*)\s*$/
77
77
  end
78
78
 
79
79
  def execute
80
80
  c = parse_thread_num_for_cmd("thread stop", @match[1])
81
- return unless c
81
+ return unless c
82
82
  c.suspend
83
83
  display_context(c)
84
84
  end
@@ -100,14 +100,14 @@ module Byebug
100
100
  self.allow_in_post_mortem = false
101
101
  self.allow_in_control = true
102
102
  self.need_context = true
103
-
103
+
104
104
  def regexp
105
105
  /^\s*th(?:read)?\s+resume\s*(\S*)\s*$/
106
106
  end
107
107
 
108
108
  def execute
109
109
  c = parse_thread_num_for_cmd("thread resume", @match[1])
110
- return unless c
110
+ return unless c
111
111
  if !c.thread.stop?
112
112
  print "Already running."
113
113
  return
@@ -136,14 +136,14 @@ module Byebug
136
136
  self.allow_in_control = true
137
137
  self.allow_in_post_mortem = false
138
138
  self.need_context = true
139
-
139
+
140
140
  def regexp
141
141
  /^\s*th(?:read)?\s*(?:sw(?:itch)?)?\s+(\S+)\s*$/
142
142
  end
143
143
 
144
144
  def execute
145
145
  c = parse_thread_num_for_cmd("thread switch", @match[1])
146
- return unless c
146
+ return unless c
147
147
  display_context(c)
148
148
  c.stop_next = 1
149
149
  c.thread.run
@@ -165,7 +165,7 @@ module Byebug
165
165
 
166
166
  class ThreadCurrentCommand < Command # :nodoc:
167
167
  self.need_context = true
168
-
168
+
169
169
  def regexp
170
170
  /^\s*th(?:read)?\s*(?:cur(?:rent)?)?\s*$/
171
171
  end
@@ -1,22 +1,22 @@
1
1
  module Byebug
2
2
  class TraceCommand < Command # :nodoc:
3
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)?
4
+ /^\s* tr(?:ace)? (?: \s+ (\S+)) # on | off | var(iable)
5
+ (?: \s+ (\S+))? # (all | variable-name)?
6
+ (?: \s+ (\S+))? \s* # (stop | nostop)?
7
7
  $/ix
8
8
  end
9
9
 
10
10
  def execute
11
11
  if @match[1] =~ /on|off/
12
12
  onoff = 'on' == @match[1]
13
- if @match[2]
13
+ #if @match[2]
14
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
15
+ print "Tracing is #{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
20
  elsif @match[1] =~ /var(?:iable)?/
21
21
  varname=@match[2]
22
22
  if debug_eval("defined?(#{varname})")
@@ -25,11 +25,10 @@ module Byebug
25
25
  else
26
26
  dbg_cmd = (@match[3] && (@match[3] !~ /nostop/)) ? 'byebug' : ''
27
27
  end
28
- eval("
29
- trace_var(:#{varname}) do |val|
30
- print \"traced variable #{varname} has value \#{val}\n\"
31
- #{dbg_cmd}
32
- end")
28
+ eval("trace_var(:#{varname}) do |val|
29
+ print \"traced variable #{varname} has value \#{val}\n\"
30
+ #{dbg_cmd}
31
+ end")
33
32
  else
34
33
  errmsg "#{varname} is not a global variable.\n"
35
34
  end
@@ -1,10 +1,12 @@
1
1
  module Byebug
2
- module VarFunctions # :nodoc:
2
+
3
+ module VarFunctions
3
4
  def var_list(ary, b = get_binding)
4
5
  ary.sort!
5
6
  for v in ary
6
7
  begin
7
- s = debug_eval(v.to_s, b).inspect
8
+ s = debug_eval(v.to_s, b).inspect unless
9
+ v == :$KCODE || v == :$-K || v == :$=
8
10
  rescue
9
11
  begin
10
12
  s = debug_eval(v.to_s, b).to_s
@@ -24,7 +26,7 @@ module Byebug
24
26
  end
25
27
  end
26
28
 
27
- # Implements the byebug 'var class' command.
29
+ # Implements byebug's 'var class' command
28
30
  class VarClassVarCommand < Command
29
31
  def regexp
30
32
  /^\s*v(?:ar)?\s+cl(?:ass)?/
@@ -33,7 +35,7 @@ module Byebug
33
35
  def execute
34
36
  unless @state.context
35
37
  errmsg "can't get class variables here.\n"
36
- return
38
+ return
37
39
  end
38
40
  var_class_self
39
41
  end
@@ -51,7 +53,7 @@ module Byebug
51
53
  end
52
54
  end
53
55
 
54
- class VarConstantCommand < Command # :nodoc:
56
+ class VarConstantCommand < Command
55
57
  def regexp
56
58
  /^\s*v(?:ar)?\s+co(?:nst(?:ant)?)?\s+/
57
59
  end
@@ -84,7 +86,7 @@ module Byebug
84
86
  end
85
87
  end
86
88
 
87
- class VarGlobalCommand < Command # :nodoc:
89
+ class VarGlobalCommand < Command
88
90
  def regexp
89
91
  /^\s*v(?:ar)?\s+g(?:lobal)?\s*$/
90
92
  end
@@ -106,7 +108,7 @@ module Byebug
106
108
  end
107
109
  end
108
110
 
109
- class VarInstanceCommand < Command # :nodoc:
111
+ class VarInstanceCommand < Command
110
112
  def regexp
111
113
  /^\s*v(?:ar)?\s+ins(?:tance)?\s*/
112
114
  end
@@ -129,7 +131,7 @@ module Byebug
129
131
  end
130
132
  end
131
133
 
132
- # Implements the byebug 'var local' command.
134
+ # Implements byebug's 'var local' command
133
135
  class VarLocalCommand < Command
134
136
  def regexp
135
137
  /^\s*v(?:ar)?\s+l(?:ocal)?\s*$/
@@ -137,7 +139,7 @@ module Byebug
137
139
 
138
140
  def execute
139
141
  locals = @state.context.frame_locals(@state.frame_pos)
140
- _self = @state.context.frame_self(@state.frame_pos)
142
+ _self = @state.context.frame_self(@state.frame_pos)
141
143
  locals.keys.sort.each do |name|
142
144
  print " %s => %p\n", name, locals[name]
143
145
  end
@@ -155,8 +157,7 @@ module Byebug
155
157
  end
156
158
  end
157
159
  end
158
-
159
- # Implements the byebug 'var inherit' command.
160
+
160
161
  begin
161
162
  require 'classtree'
162
163
  have_classtree = true
@@ -164,6 +165,7 @@ module Byebug
164
165
  have_classtree = false
165
166
  end
166
167
 
168
+ # Implements byebug's 'var inherit' command
167
169
  class VarInheritCommand < Command
168
170
  def regexp
169
171
  /^\s*v(?:ar)?\s+ct\s*/
@@ -172,7 +174,7 @@ module Byebug
172
174
  def execute
173
175
  unless @state.context
174
176
  errmsg "can't get object inheritance.\n"
175
- return
177
+ return
176
178
  end
177
179
  puts @match.post_match
178
180
  obj = debug_eval("#{@match.post_match}.classtree")
@@ -8,23 +8,10 @@ module Byebug
8
8
  end
9
9
 
10
10
  class Context
11
-
12
- def frame_locals(frame_no=0)
13
- result = {}
14
- binding = frame_binding(frame_no)
15
- locals = eval("local_variables", binding)
16
- locals.each {|local| result[local.to_s] = eval(local.to_s, binding)}
17
- result
18
- end
19
-
20
11
  def frame_class(frame_no=0)
21
12
  frame_self(frame_no).class
22
13
  end
23
14
 
24
- def frame_args_info(frame_no=0)
25
- nil
26
- end
27
-
28
15
  def interrupt
29
16
  self.stop_next = 1
30
17
  end
@@ -42,8 +29,8 @@ module Byebug
42
29
  end
43
30
 
44
31
  def at_tracing(file, line)
45
- @tracing_started = File.identical?(file, Byebug::PROG_SCRIPT)
46
- handler.at_tracing(self, file, line) if @tracing_started
32
+ handler.at_tracing(self, file, line) if
33
+ File.identical?(file, Byebug::PROG_SCRIPT)
47
34
  end
48
35
 
49
36
  def at_line(file, line)
@@ -64,6 +64,11 @@ module Byebug
64
64
  readline(prompt, false)
65
65
  end
66
66
 
67
+ # Callers of this routine should make sure to use comma to separate format
68
+ # argments rather than %. Otherwise it seems that if the string you want to
69
+ # print has format specifier, which could happen if you are trying to show
70
+ # say a source-code line with "puts" or "print" in it, this print routine
71
+ # will give an error saying it is looking for more arguments.
67
72
  def print(*args)
68
73
  STDOUT.printf(*args)
69
74
  end
@@ -1,12 +1,16 @@
1
+ require 'forwardable'
1
2
  require_relative 'interface'
2
3
  require_relative 'command'
3
4
 
4
5
  module Byebug
5
6
 
6
7
  # Should this be a mixin?
7
- class Processor # :nodoc
8
+ class Processor
8
9
  attr_accessor :interface
9
10
 
11
+ extend Forwardable
12
+ def_delegators :@interface, :errmsg, :print
13
+
10
14
  # Format msg with gdb-style annotation header
11
15
  def afmt(msg, newline="\n")
12
16
  "\032\032#{msg}#{newline}"
@@ -16,24 +20,10 @@ module Byebug
16
20
  print afmt(msg) if Byebug.annotate.to_i > 2
17
21
  end
18
22
 
19
- # FIXME: use delegate?
20
- def errmsg(*args)
21
- @interface.errmsg(*args)
22
- end
23
-
24
- # Callers of this routine should make sure to use comma to separate format
25
- # argments rather than %. Otherwise it seems that if the string you want to
26
- # print has format specifier, which could happen if you are trying to show
27
- # say a source-code line with "puts" or "print" in it, this print routine
28
- # will give an error saying it is looking for more arguments.
29
- def print(*args)
30
- @interface.print(*args)
31
- end
32
-
33
23
  end
34
24
 
35
- class CommandProcessor < Processor # :nodoc:
36
- attr_reader :display
25
+ class CommandProcessor < Processor
26
+ attr_reader :display
37
27
 
38
28
  # FIXME: get from Command regexp method.
39
29
  @@Show_breakpoints_postcmd = [
@@ -79,10 +69,12 @@ module Byebug
79
69
 
80
70
  require 'pathname' # For cleanpath
81
71
 
72
+ ##
82
73
  # Regularize file name.
83
- # This is also used as a common funnel place if basename is
84
- # desired or if we are working remotely and want to change the
85
- # basename. Or we are eliding filenames.
74
+ #
75
+ # This is also used as a common funnel place if basename is desired or if we
76
+ # are working remotely and want to change the basename. Or we are eliding
77
+ # filenames.
86
78
  def self.canonic_file(filename)
87
79
  # For now we want resolved filenames
88
80
  if Command.settings[:basename]
@@ -94,13 +86,13 @@ module Byebug
94
86
  end
95
87
 
96
88
  def self.print_location_and_text(file, line)
97
- file_line = "%s:%s\n%s" % [canonic_file(file), line,
98
- Byebug.line_at(file, line)]
89
+ file_line = "#{canonic_file(file)}:#{line}\n#{Byebug.line_at(file, line)}"
90
+
99
91
  # FIXME: use annotations routines
100
92
  if Byebug.annotate.to_i > 2
101
93
  file_line = "\032\032source #{file_line}"
102
- elsif ENV['EMACS']
103
- file_line = "\032\032#{file_line}"
94
+ #elsif ENV['EMACS']
95
+ # file_line = "\032\032#{file_line}"
104
96
  end
105
97
  print file_line
106
98
  end
@@ -132,7 +124,7 @@ module Byebug
132
124
  if Byebug.annotate.to_i > 2
133
125
  print afmt("source #{file}:#{line}")
134
126
  end
135
- print "Breakpoint %d at %s:%s\n", n, file, line
127
+ print "Stopped at breakpoint %d at %s:%s\n", n, file, line
136
128
  end
137
129
  protect :at_breakpoint
138
130
 
@@ -153,15 +145,16 @@ module Byebug
153
145
  protect :at_catchpoint
154
146
 
155
147
  def at_tracing(context, file, line)
156
- return if defined?(Byebug::RDEBUG_FILE) &&
157
- Byebug::RDEBUG_FILE == file # Don't trace ourself
158
- @last_file = CommandProcessor.canonic_file(file)
148
+ # Don't trace ourselves
149
+ return if defined?(Byebug::RDEBUG_FILE) && Byebug::RDEBUG_FILE == file
150
+
151
+ #@last_file = CommandProcessor.canonic_file(file)
159
152
  file = CommandProcessor.canonic_file(file)
160
- unless file == @last_file and @last_line == line and
161
- Command.settings[:tracing_plus]
162
- print "Tracing:%s:%s %s", file, line, Byebug.line_at(file, line)
153
+ unless file == @last_file and line == @last_line and
154
+ Command.settings[:tracing_plus]
163
155
  @last_file = file
164
156
  @last_line = line
157
+ print "Tracing: #{file}:#{line} #{Byebug.line_at(file, line)}"
165
158
  end
166
159
  always_run(context, file, line, 2)
167
160
  end
@@ -179,16 +172,23 @@ module Byebug
179
172
 
180
173
  private
181
174
 
182
- # The prompt shown before reading a command.
175
+ ##
176
+ # Prompt shown before reading a command.
177
+ #
183
178
  def prompt(context)
184
- p = '(rdb:%s) ' % (context.dead? ? 'post-mortem' : context.thnum)
179
+ p = '(byebug:%s) ' % (context.dead? ? 'post-mortem' : context.thnum)
185
180
  p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if Byebug.annotate.to_i > 2
186
181
  return p
187
182
  end
188
183
 
189
- # Run these commands, for example display commands or possibly the list or
190
- # irb in an "autolist" or "autoirb". We return a list of commands that are
191
- # acceptable to run bound to the current state.
184
+ ##
185
+ # Run commands everytime.
186
+ #
187
+ # For example display commands or possibly the list or irb in an
188
+ # "autolist" or "autoirb".
189
+ #
190
+ # @return List of commands acceptable to run bound to the current state
191
+ #
192
192
  def always_run(context, file, line, run_level)
193
193
  event_cmds = Command.commands.select{|cmd| cmd.event }
194
194
 
@@ -217,10 +217,16 @@ module Byebug
217
217
  return state, commands
218
218
  end
219
219
 
220
- # Handle byebug commands
220
+ ##
221
+ # Handle byebug commands.
222
+ #
221
223
  def process_commands(context, file, line)
222
224
  state, commands = always_run(context, file, line, 1)
223
- $rdebug_state = state if Command.settings[:byebugtesting]
225
+ if Command.settings[:byebugtesting]
226
+ $byebug_state = state
227
+ else
228
+ $byebug_state = nil
229
+ end
224
230
  splitter = lambda do |str|
225
231
  str.split(/;/).inject([]) do |m, v|
226
232
  if m.empty?
@@ -262,10 +268,12 @@ module Byebug
262
268
  postloop(commands, context)
263
269
  end # process_commands
264
270
 
271
+ ##
272
+ # Executes a single byebug command
273
+ #
265
274
  def one_cmd(commands, context, input)
266
275
  if cmd = commands.find{ |c| c.match(input) }
267
276
  if context.dead? && cmd.class.need_context
268
- p cmd
269
277
  print "Command is unavailable\n"
270
278
  else
271
279
  cmd.execute
@@ -341,13 +349,13 @@ module Byebug
341
349
 
342
350
  def display_annotations(commands, context)
343
351
  return if display.empty?
344
- # have_display = display.find{|d| d[0]}
345
- # return unless have_display and @byebug_displays_were_empty
346
- # @byebug_displays_were_empty = have_display
352
+ #have_display = display.find{|d| d[0]}
353
+ #return unless have_display and @byebug_displays_were_empty
354
+ #@byebug_displays_were_empty = have_display
347
355
  annotation('display', commands, context, "display")
348
356
  end
349
357
 
350
- class State # :nodoc:
358
+ class State
351
359
  attr_accessor :binding, :commands, :context, :display, :file, :frame_pos
352
360
  attr_accessor :interface, :line, :previous_line
353
361
 
@@ -359,18 +367,8 @@ module Byebug
359
367
  yield self
360
368
  end
361
369
 
362
- # FIXME: use delegate?
363
- def errmsg(*args)
364
- @interface.errmsg(*args)
365
- end
366
-
367
- def print(*args)
368
- @interface.print(*args)
369
- end
370
-
371
- def confirm(*args)
372
- @interface.confirm(*args)
373
- end
370
+ extend Forwardable
371
+ def_delegators :@interface, :errmsg, :print, :confirm
374
372
 
375
373
  def proceed?
376
374
  @proceed
@@ -383,7 +381,9 @@ module Byebug
383
381
 
384
382
  end # end class CommandProcessor
385
383
 
384
+
386
385
  class ControlCommandProcessor < Processor # :nodoc:
386
+
387
387
  def initialize(interface)
388
388
  super()
389
389
  @interface = interface
@@ -432,7 +432,7 @@ module Byebug
432
432
  return p
433
433
  end
434
434
 
435
- class State # :nodoc:
435
+ class State
436
436
  attr_reader :commands, :interface
437
437
 
438
438
  def initialize(interface, commands)
@@ -443,13 +443,8 @@ module Byebug
443
443
  def proceed
444
444
  end
445
445
 
446
- def errmsg(*args)
447
- @interface.print(*args)
448
- end
449
-
450
- def print(*args)
451
- @interface.print(*args)
452
- end
446
+ extend Forwardable
447
+ def_delegators :@interface, :errmsg, :print
453
448
 
454
449
  def confirm(*args)
455
450
  'y'
@@ -463,6 +458,6 @@ module Byebug
463
458
  errmsg "No filename given.\n"
464
459
  throw :debug_error
465
460
  end
466
- end # State
461
+ end
467
462
  end
468
463
  end