| 
Twylite wrote:
> >> >    TIP #329	Try/Catch/Finally syntax
> > I'd really like to see this in 8.6.  However, I also think
> > it's essential that try/catch be able to dispatch based on
> > the return code, not just $::errorCode, which the current
> > specification does not provide for.  Please fix!
> >
> Although I haven't updated the spec, the current proposal is:
>   try {
>     #code
>   } then {
>     #success continuation
>   } onerror {glob emvar optsvar} {
>     #handle errors based on errorCode
>   } except {spec emvar optsvar} {
>     #handle errors based on any matching information in optsvar
>   } finally {
>     #always execute this as the last action before leaving the try command
>   }
>
> The "except" clause will handle exceptions (non-zero Tcl return code) as
> opposed to errors (Tcl return code TCL_ERROR with dispatch based on
> errorCode).  Not certain on what the "spec" in the except clause is
> going to look like though.  Suggestions welcome (via e-mail or to
> http://wiki.tcl.tk/21608).
I would suggest:
	try {
	    ...
	} onerror {pattern ?resultVar ?optionsVar??} {
	    #
	    # return code was TCL_ERROR, errorCode matches $pattern
	    #
	} handle {code ?resultVar ?optionsVar??} {
	    #
	    # return code was $code.
	    #
	} finally {
	    ...
	}
where "code" is one of ok/error/return/break/continue
or an integer literal, a la [return -code].
If a "then" clause is desired, then
    try { # script... } then { # success continuation.. }
would be a synonym for
    try { # script... } handle ok { # success continuation ... }
although I suspect a more common usage pattern would look like:
	try {
	    open $filename "w"
	} handle {ok fp} {
	    try {
	    	# ... write to $fp
	    } finally {
		close $fp
	    }
	} onerror {{POSIX EACCESS *}} {
	    # ...
	} handle {error msg} {
	    report "Unrecognized error: $msg"
	}
> I still have concerns about this though:
> - The construct is getting pretty bulky - is it really adding power &
> simplicity as it is intended to do?
Yes.  Dispatching based on the return code is essential
for creating user-defined control structures.
> [...]
> A modification I find particularly interesting is an alternative
> approach to finally.  The current approach - while typical for try/catch
> syntax - is often a source of subtle bugs.  It is common for a finally
> to have to check each resource before cleaning it up (and equally common
> for checks to be missed or assumptions made ... e.g. if { $somevar ne {}
> } { # cleanup } but an exception was thrown before somevar was set.
>
> A nested try/then/finally may go some way to address this situation, [...]
I believe so.  Nested try/finally clauses -- one for each
resource that needs to be cleaned up -- all wrapped in
an outer try/catch for error recovery would cover
all the exception handling needs I can think of.
--Joe English
 |