Richard Suchenwirth 2003-07-29: Errors happen, and in Tcl they're less depressing and more educational than in most other languages. Also, one can try things like resuming at the position where the error happened - almost. Consider this code, where error is renamed.
rename error tcl::error
and redefined to a simple interactive prompt (a minimal debugger), where you can
proc error {code args} { puts $code/$args while 1 { puts -nonewline {% } flush stdout gets stdin line if {$line eq {x}} {tcl::error $code} if {$line eq {p}} { set self [info level -1] puts "$self {[info body [lindex $self 0]]}" continue } if {$line eq {c}} break catch {uplevel 1 $line} res puts $res } }
The test code is heavily putsy so one sees what goes on. try makes two deliberate errors: one by just calling an error, one by referencing an undefined variable.
puts {before try} proc try args { puts {in try} error intended puts x=$x puts {after error} } try a little bit puts {after try}
Experimenting with this, I find the intended error triggers indeed, I can see where I am, and it lets me fix the "missing x" bug, and resume:
suchenwi@jaguar% tclsh error2.tcl before try in try intended/ % p try a little bit { puts {in try} error intended puts x=$x puts {after error} } % set x wow! wow! % c x=wow! after error after try
but if I just let the intended error resume, missing x appears to be hard-wired to the original error, not my overloaded version:
suchenwi@jaguar% tclsh error2.tcl before try in try intended/ % c ;# continue without fixing can't read "x": no such variable while executing "puts x=$x" (procedure "try" line 4) invoked from within "try" (file "error2.tcl" line 22)
So the usability of this is limited - you can only intercept errors that you explicitly raised yourself.
An interesting point is however the behavior of the bytecode compiler: it does not notice or complain about the fact that $x is used before defined - possibly because a preceding command (like my redefined "error") might have set it with upvar...