Introduction
This is a collection of broadly useful utility code. Tcl examples throughout the rest of the guide may assume that this code is available.
Debug Printing
For better or for worse, the most common method for debugging Tcl code is to insert print statements. This can result in a lot of extraneous printing, and going through to remove all those statements is a pain (and then when you run into the next problem, you'll wish you had left them in).
Here we present two procs to allow you to turn debug printing on or off with a global variable, so you can just leave the statements in. You should always use these (or something like them) for your debug printing needs.
# define whether debugging is on (1) or off (0) set debug 1 # debugEcho -- # # If enabled, echos the name of the calling proc and all specified args # # Arguments: # Anything # Results: # Echos the debug statement to the Soar trace. proc debugEcho { args } { variable debug if { $debug } { echo "\n[callingProcName]: $args" } } # callingProcName -- # # Gets the name of the proc that called the proc that called this. # This is a helper for debugEcho # # Arguments: # None. # Results: # Returns the name of the calling proc two levels up proc callingProcName { } { return [lindex [split [info level [expr [info level] - 2]]] 0] }
debugEcho basically calls Soar's echo command with the name of the calling proc and whatever it is that you want to print. It relies on a supporting proc, CallingProcName, that basically looks two levels up to find out the name of the original calling proc (it needs to be two levels, since it is called from debugEcho, and we want what called debugEcho in the first place).
If a proc called myProc were to call debugEcho with the argument "hello world!", the output looks something like this:
myProc: hello world!
Note that if you are using jsoar, you may want to replace echo with log. This also suggests that you could enhance this to support multiple print levels, like traditional logging solutions (e.g., trace, info, debug, warn, error, etc.). Of course, if you're on jsoar, you could just use the log command directly, but wrapping it in a tcl proc improves portability, as you could easily get it to load on csoar (which has no log command) by changing this proc to use echo (or maybe even making it detect whether you're on jsoar or csoar – possibly via the version command).