ruby-debug 0.10.0 → 0.10.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.
Files changed (152) hide show
  1. data/CHANGES +94 -2
  2. data/ChangeLog +5225 -0
  3. data/README +30 -1
  4. data/Rakefile +55 -24
  5. data/bin/rdebug +249 -128
  6. data/cli/ruby-debug/command.rb +30 -3
  7. data/cli/ruby-debug/commands/breakpoints.rb +54 -24
  8. data/cli/ruby-debug/commands/catchpoint.rb +13 -12
  9. data/cli/ruby-debug/commands/condition.rb +49 -0
  10. data/cli/ruby-debug/commands/continue.rb +32 -0
  11. data/cli/ruby-debug/commands/control.rb +19 -43
  12. data/cli/ruby-debug/commands/disassemble.RB +38 -0
  13. data/cli/ruby-debug/commands/display.rb +1 -1
  14. data/cli/ruby-debug/commands/edit.rb +48 -0
  15. data/cli/ruby-debug/commands/enable.rb +78 -35
  16. data/cli/ruby-debug/commands/eval.rb +6 -5
  17. data/cli/ruby-debug/commands/finish.rb +42 -0
  18. data/cli/ruby-debug/commands/frame.rb +64 -33
  19. data/cli/ruby-debug/commands/help.rb +19 -15
  20. data/cli/ruby-debug/commands/info.rb +295 -36
  21. data/cli/ruby-debug/commands/irb.rb +3 -1
  22. data/cli/ruby-debug/commands/list.rb +27 -50
  23. data/cli/ruby-debug/commands/quit.rb +38 -0
  24. data/cli/ruby-debug/commands/reload.rb +40 -0
  25. data/cli/ruby-debug/commands/save.rb +80 -0
  26. data/cli/ruby-debug/commands/{settings.rb → set.rb} +50 -12
  27. data/cli/ruby-debug/commands/show.rb +83 -27
  28. data/cli/ruby-debug/commands/source.rb +36 -0
  29. data/cli/ruby-debug/commands/stepping.rb +36 -72
  30. data/cli/ruby-debug/commands/threads.rb +32 -23
  31. data/cli/ruby-debug/commands/variables.rb +34 -4
  32. data/cli/ruby-debug/helper.rb +10 -75
  33. data/cli/ruby-debug/interface.rb +72 -9
  34. data/cli/ruby-debug/processor.rb +203 -100
  35. data/doc/rdebug.1 +7 -2
  36. data/rdbg.rb +33 -0
  37. data/test/{test-ruby-debug-base.rb → base/base.rb} +27 -29
  38. data/test/base/binding.rb +31 -0
  39. data/test/base/catchpoint.rb +26 -0
  40. data/test/base/load.rb +40 -0
  41. data/test/data/annotate.cmd +29 -0
  42. data/test/data/annotate.right +137 -0
  43. data/test/data/break_bad.cmd +18 -0
  44. data/test/data/break_bad.right +28 -0
  45. data/test/data/breakpoints.cmd +38 -0
  46. data/test/data/breakpoints.right +98 -0
  47. data/test/data/condition.cmd +28 -0
  48. data/test/data/condition.right +65 -0
  49. data/test/data/ctrl.cmd +23 -0
  50. data/test/data/ctrl.right +69 -0
  51. data/test/{display.cmd → data/display.cmd} +7 -1
  52. data/test/{display.right → data/display.right} +13 -6
  53. data/test/data/dollar-0.right +2 -0
  54. data/test/data/dollar-0a.right +2 -0
  55. data/test/data/dollar-0b.right +2 -0
  56. data/test/data/edit.cmd +12 -0
  57. data/test/data/edit.right +19 -0
  58. data/test/{breakpoints.cmd → data/emacs_basic.cmd} +0 -0
  59. data/test/{breakpoints.right → data/emacs_basic.right} +24 -12
  60. data/test/data/enable.cmd +20 -0
  61. data/test/data/enable.right +36 -0
  62. data/test/data/finish.cmd +16 -0
  63. data/test/data/finish.right +43 -0
  64. data/test/{frame.cmd → data/frame.cmd} +2 -0
  65. data/test/{frame.right → data/frame.right} +8 -2
  66. data/test/{help.cmd → data/help.cmd} +8 -0
  67. data/test/data/help.right +21 -0
  68. data/test/data/history.right +7 -0
  69. data/test/data/info-thread.cmd +13 -0
  70. data/test/data/info-thread.right +37 -0
  71. data/test/data/info-var-bug2.cmd +5 -0
  72. data/test/data/info-var-bug2.right +10 -0
  73. data/test/{info-var.cmd → data/info-var.cmd} +3 -3
  74. data/test/{info-var.right → data/info-var.right} +20 -15
  75. data/test/{info.cmd → data/info.cmd} +10 -1
  76. data/test/data/info.right +65 -0
  77. data/test/data/linetrace.cmd +6 -0
  78. data/test/data/linetrace.right +32 -0
  79. data/test/data/linetracep.cmd +7 -0
  80. data/test/data/linetracep.right +25 -0
  81. data/test/data/list.cmd +19 -0
  82. data/test/data/list.right +127 -0
  83. data/test/data/noquit.right +1 -0
  84. data/test/data/output.cmd +6 -0
  85. data/test/data/output.right +41 -0
  86. data/test/data/post-mortem-next.cmd +8 -0
  87. data/test/data/post-mortem-next.right +14 -0
  88. data/test/data/post-mortem-osx.right +31 -0
  89. data/test/data/post-mortem.cmd +13 -0
  90. data/test/data/post-mortem.right +31 -0
  91. data/test/{quit.cmd → data/quit.cmd} +2 -5
  92. data/test/data/quit.right +9 -0
  93. data/test/data/raise.cmd +11 -0
  94. data/test/data/raise.right +26 -0
  95. data/test/{setshow.cmd → data/setshow.cmd} +0 -1
  96. data/test/{setshow.right → data/setshow.right} +0 -1
  97. data/test/data/source.cmd +5 -0
  98. data/test/data/source.right +15 -0
  99. data/test/{stepping.cmd → data/stepping.cmd} +6 -2
  100. data/test/{stepping.right → data/stepping.right} +13 -3
  101. data/test/data/test-init-cygwin.right +7 -0
  102. data/test/data/test-init-osx.right +4 -0
  103. data/test/data/test-init.right +5 -0
  104. data/test/data/trace.right +23 -0
  105. data/test/dollar-0.rb +5 -0
  106. data/test/except-bug2.rb +7 -0
  107. data/test/gcd-dbg-nox.rb +31 -0
  108. data/test/gcd-dbg.rb +30 -0
  109. data/test/helper.rb +44 -14
  110. data/test/info-var-bug.rb +2 -0
  111. data/test/info-var-bug2.rb +2 -0
  112. data/test/null.rb +1 -0
  113. data/test/output.rb +2 -0
  114. data/test/pm-base.rb +22 -0
  115. data/test/pm.rb +11 -0
  116. data/test/raise.rb +3 -0
  117. data/test/tdebug.rb +88 -40
  118. data/test/test-annotate.rb +25 -0
  119. data/test/test-break-bad.rb +25 -0
  120. data/test/test-breakpoints.rb +14 -17
  121. data/test/test-condition.rb +25 -0
  122. data/test/test-ctrl.rb +54 -0
  123. data/test/test-display.rb +15 -15
  124. data/test/test-dollar-0.rb +39 -0
  125. data/test/test-edit.rb +26 -0
  126. data/test/test-emacs-basic.rb +26 -0
  127. data/test/test-enable.rb +25 -0
  128. data/test/test-finish.rb +34 -0
  129. data/test/test-frame.rb +15 -16
  130. data/test/test-help.rb +34 -18
  131. data/test/test-hist.rb +68 -0
  132. data/test/test-info-thread.rb +32 -0
  133. data/test/test-info-var.rb +28 -14
  134. data/test/test-info.rb +15 -17
  135. data/test/test-init.rb +41 -0
  136. data/test/test-list.rb +25 -0
  137. data/test/test-output.rb +26 -0
  138. data/test/test-pm.rb +46 -0
  139. data/test/test-quit.rb +19 -17
  140. data/test/test-raise.rb +25 -0
  141. data/test/test-setshow.rb +14 -13
  142. data/test/test-source.rb +25 -0
  143. data/test/test-stepping.rb +14 -14
  144. data/test/test-trace.rb +63 -0
  145. data/test/thread1.rb +26 -0
  146. metadata +125 -31
  147. data/cli/ruby-debug/commands/script.rb +0 -64
  148. data/runner.sh +0 -7
  149. data/test/help.right +0 -4
  150. data/test/info.right +0 -35
  151. data/test/quit.right +0 -22
  152. data/test/test-columnize.rb +0 -46
@@ -1,16 +1,39 @@
1
+ require 'rubygems'
2
+ require 'columnize'
1
3
  require 'ruby-debug/helper'
2
4
 
3
5
  module Debugger
6
+ RUBY_DEBUG_DIR = File.expand_path(File.dirname(__FILE__)) unless
7
+ defined?(RUBY_DEBUG_DIR)
4
8
 
5
9
  class Command # :nodoc:
10
+ SubcmdStruct=Struct.new(:name, :min, :short_help, :long_help) unless
11
+ defined?(SubcmdStruct)
12
+
13
+ include Columnize
14
+
15
+ # Find param in subcmds. param id downcased and can be abbreviated
16
+ # to the minimum length listed in the subcommands
17
+ def find(subcmds, param)
18
+ param.downcase!
19
+ for try_subcmd in subcmds do
20
+ if (param.size >= try_subcmd.min) and
21
+ (try_subcmd.name[0..param.size-1] == param)
22
+ return try_subcmd
23
+ end
24
+ end
25
+ return nil
26
+ end
27
+
6
28
  class << self
7
29
  def commands
8
30
  @commands ||= []
9
31
  end
10
32
 
11
33
  DEF_OPTIONS = {
34
+ :allow_in_control => false,
35
+ :allow_in_post_mortem => true,
12
36
  :event => true,
13
- :control => false,
14
37
  :always_run => 0,
15
38
  :unknown => false,
16
39
  :need_context => false,
@@ -24,8 +47,7 @@ module Debugger
24
47
  end
25
48
 
26
49
  def load_commands
27
- dir = File.dirname(__FILE__)
28
- Dir[File.join(dir, 'commands', '*')].each do |file|
50
+ Dir[File.join(Debugger.const_get(:RUBY_DEBUG_DIR), 'commands', '*')].each do |file|
29
51
  require file if file =~ /\.rb$/
30
52
  end
31
53
  Debugger.constants.grep(/Functions$/).map { |name| Debugger.const_get(name) }.each do |mod|
@@ -134,6 +156,11 @@ module Debugger
134
156
 
135
157
  protected
136
158
 
159
+ # FIXME: use delegate?
160
+ def errmsg(*args)
161
+ @state.errmsg(*args)
162
+ end
163
+
137
164
  def print(*args)
138
165
  @state.print(*args)
139
166
  end
@@ -1,18 +1,12 @@
1
1
  module Debugger
2
2
  class AddBreakpoint < Command # :nodoc:
3
- self.control = true
3
+ self.allow_in_control = true
4
4
 
5
5
  def regexp
6
6
  / ^\s*
7
7
  b(?:reak)?
8
- (?: \s+
9
- (?:
10
- (\d+) |
11
- (.+?)[:.#]([^.:\s]+)
12
- ))?
13
- (?:\s+
14
- if\s+(.+)
15
- )?
8
+ (?: \s+ #{Position_regexp})? \s*
9
+ (?: \s+ (.*))? \s*
16
10
  $
17
11
  /x
18
12
  end
@@ -23,10 +17,26 @@ module Debugger
23
17
  else
24
18
  _, file, line, expr = @match.captures
25
19
  end
20
+ if expr
21
+ if expr !~ /^\s*if\s+(.+)/
22
+ if file or line
23
+ errmsg "Expecting 'if' in breakpoint condition; got: #{expr}.\n"
24
+ else
25
+ errmsg "Invalid breakpoint location: #{expr}.\n"
26
+ end
27
+ return
28
+ else
29
+ expr = $1
30
+ end
31
+ end
26
32
 
27
- full_file = nil
33
+ brkpt_filename = nil
28
34
  if file.nil?
29
- full_file = @state.file
35
+ unless @state.context
36
+ errmsg "We are not in a state that has an associated file.\n"
37
+ return
38
+ end
39
+ brkpt_filename = @state.file
30
40
  file = File.basename(@state.file)
31
41
  if line.nil?
32
42
  # Set breakpoint at current line
@@ -38,25 +48,41 @@ module Debugger
38
48
  if klass && klass.kind_of?(Module)
39
49
  class_name = klass.name if klass
40
50
  else
41
- print "Unknown class #{file}.\n"
51
+ errmsg "Unknown class #{file}.\n"
42
52
  throw :debug_error
43
53
  end
44
54
  else
55
+ # FIXME: This should be done in LineCache.
45
56
  file = File.expand_path(file) if file.index(File::SEPARATOR) || \
46
57
  File::ALT_SEPARATOR && file.index(File::ALT_SEPARATOR)
47
- full_file = file
58
+ brkpt_filename = file
48
59
  end
49
60
 
50
61
  if line =~ /^\d+$/
51
62
  line = line.to_i
52
- lines = Debugger.source_for(full_file)
53
- if not lines
54
- print "No source file named %s\n", file
55
- elsif lines.size < line
56
- print "No line %d in file \"%s\"\n", line, file
57
- else
58
- b = Debugger.add_breakpoint file, line, expr
59
- print "Breakpoint %d file %s, line %s\n", b.id, file, line.to_s
63
+ unless LineCache.cache(brkpt_filename,
64
+ Command.settings[:reload_source_on_change])
65
+ errmsg("No source file named %s\n", file)
66
+ return
67
+ end
68
+ last_line = LineCache.size(brkpt_filename)
69
+ if line > last_line
70
+ errmsg("There are only %d lines in file \"%s\".\n", last_line, file)
71
+ return
72
+ end
73
+ unless LineCache.trace_line_numbers(brkpt_filename).member?(line)
74
+ errmsg("Line %d is not a stopping point in file \"%s\".\n", line, file)
75
+ return
76
+ end
77
+ unless @state.context
78
+ errmsg "We are not in a state we can add breakpoints.\n"
79
+ return
80
+ end
81
+ b = Debugger.add_breakpoint file, line, expr
82
+ print "Breakpoint %d file %s, line %s\n", b.id, brkpt_filename, line.to_s
83
+ unless syntax_valid?(expr)
84
+ errmsg("Expression \"#{expr}\" syntactically incorrect; breakpoint disabled.\n")
85
+ b.enabled = false
60
86
  end
61
87
  else
62
88
  method = line.intern.id2name
@@ -81,13 +107,17 @@ module Debugger
81
107
  end
82
108
 
83
109
  class DeleteBreakpointCommand < Command # :nodoc:
84
- self.control = true
110
+ self.allow_in_control = true
85
111
 
86
112
  def regexp
87
- /^\s*del(?:ete)?(?:\s+(.*))?$/
113
+ /^\s *del(?:ete)? (?:\s+(.*))?$/ix
88
114
  end
89
115
 
90
116
  def execute
117
+ unless @state.context
118
+ errmsg "We are not in a state we can delete breakpoints.\n"
119
+ return
120
+ end
91
121
  brkpts = @match[1]
92
122
  unless brkpts
93
123
  if confirm("Delete all breakpoints? (y or n) ")
@@ -98,7 +128,7 @@ module Debugger
98
128
  pos = get_int(pos, "Delete", 1)
99
129
  return unless pos
100
130
  unless Debugger.remove_breakpoint(pos)
101
- print "No breakpoint number %d\n", pos
131
+ errmsg "No breakpoint number %d\n", pos
102
132
  end
103
133
  end
104
134
  end
@@ -1,9 +1,9 @@
1
1
  module Debugger
2
2
  class CatchCommand < Command # :nodoc:
3
- self.control = true
3
+ self.allow_in_control = true
4
4
 
5
5
  def regexp
6
- /^\s*cat(?:ch)?(?:\s+(.+))?$/
6
+ /^\s* cat(?:ch)? (?:\s+(.+))? $/x
7
7
  end
8
8
 
9
9
  def execute
@@ -12,15 +12,15 @@ module Debugger
12
12
  Debugger.catchpoint = nil
13
13
  print "Clear catchpoint.\n"
14
14
  else
15
- Debugger.catchpoint = excn
16
- print "Set catchpoint %s.\n", excn
15
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
16
+ unless debug_eval("#{excn}.is_a?(Class)", binding)
17
+ print "Warning #{excn} is not known to be a Class\n"
18
+ end
19
+ Debugger.add_catchpoint(excn)
20
+ print "Catch exception %s.\n", excn
17
21
  end
18
22
  else
19
- if Debugger.catchpoint
20
- print "Catchpoint %s.\n", Debugger.catchpoint
21
- else
22
- print "No catchpoint.\n"
23
- end
23
+ info_catch
24
24
  end
25
25
  end
26
26
 
@@ -31,10 +31,11 @@ module Debugger
31
31
 
32
32
  def help(cmd)
33
33
  %{
34
- cat[ch]\t\t\tshow catchpoint
35
- cat[ch] <an Exception>\tset catchpoint to an exception
34
+ cat[ch]\t\t\tsame as "info catch"
35
+ cat[ch] <exception-name>\tIntercept <exception-name> when there would otherwise be is no handler
36
+ for it.
36
37
  }
37
38
  end
38
39
  end
39
40
  end
40
- end
41
+ end
@@ -0,0 +1,49 @@
1
+ module Debugger
2
+
3
+ class ConditionCommand < Command # :nodoc:
4
+
5
+ def regexp
6
+ /^\s* cond(?:ition)? (?:\s+(\d+)\s*(.*))?$/ix
7
+ end
8
+
9
+ def execute
10
+ if not @match[1]
11
+ errmsg "\"condition\" must be followed a breakpoint number and expression\n"
12
+ else
13
+ breakpoints = Debugger.breakpoints.sort_by{|b| b.id }
14
+ largest = breakpoints.inject(0) do |largest, b|
15
+ largest = b.id if b.id > largest
16
+ end
17
+ if 0 == largest
18
+ print "No breakpoints have been set.\n"
19
+ return
20
+ end
21
+ pos = get_int(@match[1], "Condition", 1, largest)
22
+ return unless pos
23
+ breakpoints.each do |b|
24
+ if b.id == pos
25
+ b.expr = @match[2].empty? ? nil : @match[2]
26
+ break
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+
33
+ class << self
34
+ def help_command
35
+ 'condition'
36
+ end
37
+
38
+ def help(cmd)
39
+ %{
40
+ Condition breakpoint-number expression
41
+ Specify breakpoint number N to break only if COND is true.
42
+ N is an integer and COND is an expression to be evaluated whenever
43
+ breakpoint N is reached. If the empty string is used, the condition is removed.
44
+ }
45
+ end
46
+ end
47
+ end
48
+
49
+ end # module Debugger
@@ -0,0 +1,32 @@
1
+ module Debugger
2
+ # Implements debugger "continue" command.
3
+ class ContinueCommand < Command
4
+ self.allow_in_post_mortem = false
5
+ self.need_context = true
6
+ def regexp
7
+ /^\s* c(?:ont(?:inue)?)? (?:\s+(.*))? $/x
8
+ end
9
+
10
+ def execute
11
+ if @match[1] && !@state.context.dead?
12
+ file = File.expand_path(@state.file)
13
+ line = get_int(@match[1], "Continue", 0, nil, 0)
14
+ return unless line
15
+ @state.context.set_breakpoint(file, line)
16
+ end
17
+ @state.proceed
18
+ end
19
+
20
+ class << self
21
+ def help_command
22
+ 'continue'
23
+ end
24
+
25
+ def help(cmd)
26
+ %{
27
+ c[ont[inue]][ nnn]\trun until program ends, hits a breakpoint or reaches line nnn
28
+ }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,37 +1,6 @@
1
1
  module Debugger
2
- class QuitCommand < Command # :nodoc:
3
- self.control = true
4
-
5
- def regexp
6
- /^\s*(?:q(?:uit)?|exit)\s*(\s+unconditionally)?\s*$/
7
- end
8
-
9
- def execute
10
- if @match[1] or confirm("Really quit? (y/n) ")
11
- Debugger.save_history if Debugger.respond_to? :save_history
12
- exit! # exit -> exit!: No graceful way to stop threads...
13
- end
14
- end
15
-
16
- class << self
17
- def help_command
18
- %w[quit exit]
19
- end
20
-
21
- def help(cmd)
22
- %{
23
- q[uit] [unconditionally]\texit from debugger.
24
- exit\talias to quit
25
-
26
- Normally we prompt before exiting. However if the parameter
27
- "unconditionally" is given, we stop without asking further questions.
28
- }
29
- end
30
- end
31
- end
32
-
33
2
  class RestartCommand < Command # :nodoc:
34
- self.control = true
3
+ self.allow_in_control = true
35
4
 
36
5
  def regexp
37
6
  / ^\s*
@@ -42,40 +11,46 @@ module Debugger
42
11
  end
43
12
 
44
13
  def execute
14
+ if not defined? Debugger::PROG_SCRIPT
15
+ errmsg "Don't know name of debugged program\n"
16
+ return
17
+ end
18
+ prog_script = Debugger::PROG_SCRIPT
45
19
  if not defined? Debugger::RDEBUG_SCRIPT
46
20
  # FIXME? Should ask for confirmation?
47
21
  print "Debugger was not called from the outset...\n"
48
- rdebug_script = ''
22
+ rdebug_script = prog_script
49
23
  else
50
- rdebug_script = Debugger::RDEBUG_SCRIPT + " "
24
+ rdebug_script = Debugger::RDEBUG_SCRIPT
51
25
  end
52
- prog_script = Debugger::PROG_SCRIPT
53
26
  begin
54
27
  Dir.chdir(Debugger::INITIAL_DIR)
55
28
  rescue
56
29
  print "Failed to change initial directory #{Debugger::INITIAL_DIR}"
57
30
  end
58
- if not File.exists?(prog_script)
59
- print "Ruby program #{prog_script} doesn't exist\n"
31
+ if not File.exist?(File.expand_path(prog_script))
32
+ errmsg "Ruby program #{prog_script} doesn't exist\n"
60
33
  return
61
34
  end
62
- if not File.executable?(prog_script) and rdebug_script == ''
35
+ if not File.executable?(prog_script) and rdebug_script == prog_script
63
36
  print "Ruby program #{prog_script} doesn't seem to be executable...\n"
64
37
  print "We'll add a call to Ruby.\n"
65
38
  ruby = begin defined?(Gem) ? Gem.ruby : "ruby" rescue "ruby" end
66
39
  rdebug_script = "#{ruby} -I#{$:.join(' -I')} #{prog_script}"
40
+ else
41
+ rdebug_script += ' '
67
42
  end
68
43
  if @match[1]
69
44
  argv = [prog_script] + @match[1].split(/[ \t]+/)
70
45
  else
71
46
  if not defined? Command.settings[:argv]
72
- print "Arguments have not been set. Use 'set args' to set them.\n"
47
+ errmsg "Arguments have not been set. Use 'set args' to set them.\n"
73
48
  return
74
49
  else
75
50
  argv = Command.settings[:argv]
76
51
  end
77
52
  end
78
- args = argv.join(" ")
53
+ args = argv.join(' ')
79
54
 
80
55
  # An execv would be preferable to the "exec" below.
81
56
  cmd = rdebug_script + args
@@ -101,9 +76,10 @@ module Debugger
101
76
  end
102
77
 
103
78
  class InterruptCommand < Command # :nodoc:
104
- self.event = false
105
- self.control = true
106
- self.need_context = true
79
+ self.allow_in_control = true
80
+ self.allow_in_post_mortem = false
81
+ self.event = false
82
+ self.need_context = true
107
83
 
108
84
  def regexp
109
85
  /^\s*i(?:nterrupt)?\s*$/
@@ -0,0 +1,38 @@
1
+ module Debugger
2
+
3
+ require 'pp'
4
+ require 'nodepp'
5
+ require 'classtree'
6
+ require 'parse_tree'
7
+ class Disassemble < Command # :nodoc:
8
+ self.allow_in_control = false
9
+ @@parse_tree = ParseTree.new(true)
10
+
11
+ def regexp
12
+ /^\s*(dis(?:assemble)?)\s+/
13
+ end
14
+
15
+ def execute
16
+ expr = @match ? @match.post_match : @input
17
+ binding = @state.context ? get_binding : TOPLEVEL_BINDING
18
+ method_str = "method(:#{expr})"
19
+ if method_obj = debug_eval(method_str, binding)
20
+ print @@parse_tree.parse_tree_for_method(method_obj.class,
21
+ method_str).inspect
22
+ print "#{method_obj}\n"
23
+ end
24
+ end
25
+
26
+ class << self
27
+ def help_command
28
+ %w|disassemble method-name|
29
+ end
30
+
31
+ def help(cmd)
32
+ %{
33
+ dis[assemble] method-name\tdo live unparsing of method name
34
+ }
35
+ end
36
+ end
37
+ end if false
38
+ end