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
- check what went wrong ("p" to see the proc body where the error happened, and the arguments with which it was called),
- maybe fix it, and decide to
- "c"ontinue (i.e. resume after the place the error was raised) or
- keep the error for the real handler ("x"):
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...
See Also edit
- procstep
- A script monitor that provides full control over the evalution of the script, making things like full restarts feasible to implement in pure Tcl.