On 30/06/2016 09:16, Roger Oberholtzer wrote:
> Will the finally {} still be able to execute the close in the context of the proc?
Yes. It traps the [return]'s special exception, runs the finally block,
and then re-throws the [return] which makes the procedure actually
return. It'd be nothing like so useful if this didn't Just Work. :-) If
you want to explore what's going on in detail, try this:
set returnCode [catch {
return "a dummy value"
} message statusDictionary]
puts "return code was $returnCode"
puts "result was '$message'"
puts "status dictionary:"
dict for {k v} $statusDictionary {puts "\t${k}: ${v}"}
Run that and you'll get this output:
return code was 2
result was 'a dummy value'
status dictionary:
-code: 0
-level: 1
The '2' is the result code TCL_RETURN. The '0' is TCL_OK, the result
code to use from the procedure. The -level is how many levels of stack
frame (or is that levels of procedure?) to unwind; '1' is normal for a
basic [return].
One of the points of putting [try] into Tcl was to make exactly this
sort of thing much easier. It does nothing you couldn't do with [catch]
and some scripting, but doing that is really annoying: [try] hides the
mess and lets you write clearer code. In fact, the only thing you need
to watch out for is whether your 'finally' clause throws an error: if it
does, it can make it harder to work out what the main body was up to.
The variable lifespan is to the end of the procedure (or an explicit
[unset]), not to the point where [return] was called. That was always
the case.
Donal.
--
Donal Fellows — Tcl user, Tcl maintainer, TIP editor.