| Class | Debugger::Command |
| In: |
cli/ruby-debug/command.rb
|
| Parent: | Object |
A Debugger::Command object is is the base class for commands that implement a single debugger command. Individual debugger commands will be a subclass of this. The singleton class object is the command manager for all commands.
Each debugger command is expected to implement the following methods:
| regexp: | A regular expression which input strings are matched against. If we have a match, run this command. It is the ruby-debug programmer‘s responsibility to make sure that these regular expressions match disjoint sets of strings. Otherwise one is arbitrarily used. |
| execute: | Ruby code that implements the command. |
| help: | Should return a String containing descriptive help for the commmand. Used by the ‘help’ command Debugger::HelpCommand |
| help_command: | The name of the command listed via help. |
help and help_command methods are singleton methods, not instance methods like regexp and execute.
| SubcmdStruct | = | Struct.new(:name, :min, :short_help, :long_help) unless defined?(SubcmdStruct) |
| DEF_OPTIONS | = | { :allow_in_control => false, :allow_in_post_mortem => true, :event => true, :always_run => 0, :unknown => false, :need_context => false, } unless defined?(DEF_OPTIONS) |
| ARGV | = | ARGV.clone |
An Array containing Debugger::Command classes that implment each of the debugger commands.
# File cli/ruby-debug/command.rb, line 49
49: def commands
50: @commands ||= []
51: end
# File cli/ruby-debug/command.rb, line 62
62: def inherited(klass)
63: DEF_OPTIONS.each do |o, v|
64: klass.options[o] = v if klass.options[o].nil?
65: end
66: commands << klass
67: end
Read in and "include" all the subclasses of the Debugger::Command class. For example Debugger::QuitCommand is one of them. The list of Ruby files to read are all the files that end .rb in directory Debugger::RUBY_DEBUG_DIR
# File cli/ruby-debug/command.rb, line 74
74: def load_commands
75: Dir[File.join(Debugger.const_get(:RUBY_DEBUG_DIR), 'commands', '*')].each do |file|
76: require file if file =~ /\.rb$/
77: end
78: Debugger.constants.grep(/Functions$/).map { |name| Debugger.const_get(name) }.each do |mod|
79: include mod
80: end
81: end
# File cli/ruby-debug/command.rb, line 83
83: def method_missing(meth, *args, &block)
84: if meth.to_s =~ /^(.+?)=$/
85: @options[$1.intern] = args.first
86: else
87: if @options.has_key?(meth)
88: @options[meth]
89: else
90: super
91: end
92: end
93: end
# File cli/ruby-debug/command.rb, line 145
145: def register_setting_get(name, &block)
146: settings_map[name] ||= {}
147: settings_map[name][:getter] = block
148: end
# File cli/ruby-debug/command.rb, line 150
150: def register_setting_set(name, &block)
151: settings_map[name] ||= {}
152: settings_map[name][:setter] = block
153: end
# File cli/ruby-debug/command.rb, line 138
138: def register_setting_var(name, default)
139: var_name = "@@#{name}"
140: class_variable_set(var_name, default)
141: register_setting_get(name) { class_variable_get(var_name) }
142: register_setting_set(name) { |value| class_variable_set(var_name, value) }
143: end
Returns a Hash of Debugger settings, @settings. If doesn‘t exist we create a @settings hash with [] setter and getter and return that.
# File cli/ruby-debug/command.rb, line 106
106: def settings
107: unless true and defined? @settings and @settings
108: @settings = Object.new
109: map = settings_map
110: c = class << @settings; self end
111: if c.respond_to?(:funcall)
112: c.funcall(:define_method, :[]) do |name|
113: raise "No such setting #{name}" unless map.has_key?(name)
114: map[name][:getter].call
115: end
116: else
117: c.send(:define_method, :[]) do |name|
118: raise "No such setting #{name}" unless map.has_key?(name)
119: map[name][:getter].call
120: end
121: end
122: c = class << @settings; self end
123: if c.respond_to?(:funcall)
124: c.funcall(:define_method, :[]=) do |name, value|
125: raise "No such setting #{name}" unless map.has_key?(name)
126: map[name][:setter].call(value)
127: end
128: else
129: c.send(:define_method, :[]=) do |name, value|
130: raise "No such setting #{name}" unless map.has_key?(name)
131: map[name][:setter].call(value)
132: end
133: end
134: end
135: @settings
136: end
Find param in subcmds. The param id downcased and can be abbreviated to the minimum length listed in the subcommands
# File cli/ruby-debug/command.rb, line 35
35: def find(subcmds, param)
36: param.downcase!
37: for try_subcmd in subcmds do
38: if (param.size >= try_subcmd.min) and
39: (try_subcmd.name[0..param.size-1] == param)
40: return try_subcmd
41: end
42: end
43: return nil
44: end
# File cli/ruby-debug/command.rb, line 180
180: def match(input)
181: @match = regexp.match(input)
182: end
Called when we are about to do a dangerous operation. msg contains a prompt message. Return true if confirmed or false if not confirmed.
# File cli/ruby-debug/command.rb, line 198
198: def confirm(msg)
199: @state.confirm(msg) == 'y'
200: end
debug_eval like Kernel.eval or Object.instance_eval but using the bindings for the debugged program. If there is a syntax-error like exception in running eval, print an appropriate message and throw :debug_error
# File cli/ruby-debug/command.rb, line 206
206: def debug_eval(str, b = get_binding)
207: begin
208: val = eval(str, b)
209: rescue StandardError, ScriptError => e
210: if Command.settings[:stack_trace_on_error]
211: at = eval("caller(1)", b)
212: print "%s:%s\n", at.shift, e.to_s.sub(/\(eval\):1:(in `.*?':)?/, '')
213: for i in at
214: print "\tfrom %s\n", i
215: end
216: else
217: print "#{e.class} Exception: #{e.message}\n"
218: end
219: throw :debug_error
220: end
221: end
debug_eval like Kernel.eval or Object.instance_eval but using the bindings for the debugged program. If there is a syntax error kind of exception in running eval, no warning is given and nil is returned.
# File cli/ruby-debug/command.rb, line 227
227: def debug_silent_eval(str)
228: begin
229: eval(str, get_binding)
230: rescue StandardError, ScriptError
231: nil
232: end
233: end
FIXME: use delegate?
# File cli/ruby-debug/command.rb, line 187
187: def errmsg(*args)
188: @state.errmsg(*args)
189: end
Return a binding object for the debugged program.
# File cli/ruby-debug/command.rb, line 236
236: def get_binding
237: @state.context.frame_binding(@state.frame_pos)
238: end
# File cli/ruby-debug/command.rb, line 244
244: def get_context(thnum)
245: Debugger.contexts.find{|c| c.thnum == thnum}
246: end
# File cli/ruby-debug/command.rb, line 240
240: def line_at(file, line)
241: Debugger.line_at(file, line)
242: end