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