Skip to content

Evaluating the current source line before it runs

rocky edited this page Mar 2, 2011 · 3 revisions

I often find that what I want to do inside a debugger is evaluate the statement that is about to be run to check it.

The debugger command to evaluate some code is called eval. This command tends not to be used that much for two reasons. First, if the command you want to run can’t be confused with a debugger command and “autoeval” is set on, you can do the same thing by omitting, the word “eval”. Second if the debugger command line starts with ‘!’ that is hard-wired to evaluate the line. (However it is not an alias for eval. For example:

(trepan): ! s 5  # is not a step command but is the same as s(5)
(trepan): !!f(x) # same as Ruby !f(x), not !!f(x)

So now we get to the new stuff. If you give the debugger command eval with no additional string, the current line of code is evaluated.

Here’s an example:

-- (/usr/local/lib/ruby/1.9.1/irb/init.rb:30 @4)
@TRACER_INITIALIZED = false
(trepan): eval
eval: @TRACER_INITIALIZED = false
false
(trepan): 

This was working fine, until I started coming across tests inside if, elsif, and until blocks. For example:

-- (/usr/local/lib/ruby/1.9.1/irb/init.rb:33 @11)
unless ap_path and @CONF[:AP_NAME]
(trepan): list
 28    	  def IRB.init_config(ap_path)
 29    	    # class instance variables
 30    	    @TRACER_INITIALIZED = false
 31    	
 32    	    # default configurations
 33  ->	    unless ap_path and @CONF[:AP_NAME]
 34    	      ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
 35    	    end
 36    	    @CONF[:AP_NAME] = File::basename(ap_path, ".rb")
 37    	
(trepan): 

What I would like to do here is to strip off the leading reserved word (until here) and run the rest.

If you alias a command ending in “?” to eval, then those various reserved words are strip off the current source line and various common suffixes words like then or do may also be stripped. By default, eval? and ev? are aliased to eval.

Here is an example:

-- (/usr/local/lib/ruby/1.9.1/irb/init.rb:33 @11)
unless ap_path and @CONF[:AP_NAME]
(trepan): eval?
eval: ap_path and @CONF[:AP_NAME]
nil
(trepan): 

More generally, I think of these things as a work-around for a more general desire that one would like be able to handle reverse execution. This is a harder and adding it would add much more overhead. So I should also here one mention related command in the trepanning debuggers which look backwards: set trace buffer and show trace buffer *n*.