|
From: Magentus <mag...@gm...> - 2008-11-25 04:31:21
|
On Sun, 23 Nov 2008 19:55:51 +0200,
Twylite <tw...@cr...> wrote:
>> In block (1), $var holds an open file handle;
>> in block (2) it holds an error message.
> This is of course what you get from [catch] at present.
>> Personally I'd prefer having different variable names
>> in the different branches:
> Your objection has been forwarded to Fredderic and NEM.
If the vars can be shoe-horned into each branch optionally, or at least
not too ugly, I'm all for it, personally.
My main concern was the complexity of trying to fit everything into the
one statement. If you try to match a decent-length error message, add
two decently descriptive variable names, a level or two of indenting,
and the handler command, you can all too easily end up having to split
it over two which is going to totally frag any hope of visual clarity.
A little effort on picking purpose-neutral variable names (as you have
to do with [catch] already) allows you to define it once up front, and
keep the individual handler lines short and sweet. How's this as an
idea to combine the "no matching is needed" thoughts...
try script
as {vars}
handler ?-- errorcode-pattern? body
return ?-- returnvalue-patten? body
on {code ?-- returnvalue-pattern?} body
finally body
The -- "option" here indicates there is a pattern to match, but will
later be the place holder for the match type if there's consensus that
"beyond-glob" matching is needed.
This allows you omit the pattern string, and divide the inevitable
embedded [switch] statement into per-code blocks with whatever matcher
you wish:
try {
script
} as {
response options
} return {
switch -regexp ... {
... different kinds of OK response ...
}
} handler -- "POSIX *" {
switch -exact -- [lindex $response 1] {
... match the gauntlet of Posix errorx ...
}
} on error {
switch -- $response {
... traditional (bad) error returning ...
}
} expr {some freaky conditional stuff} {
... do the jolly jumbuck ...
} finally {
cleanup
}
Clean, minimal if you want it to be, hugely flexible when you need it,
you can add other types of pattern matching later (the sentinel is
there for when it's needed, AND it's actually being used so it'll
already be there avoiding future compatibility issues), and you can
still allow for plugging in other types of [try] keyword (in place of
as, handler, on, expr, and finally).
Of course, it could be -pattern in place of just --, or something like
that. I'd rather avoid -match here, because as another post suggests,
I'd like to see that used for a generic pattern matching framework that
wold be consistent across all TCL commands, and remove the constant
expanding mass of match type options. (If I remember correctly we've
already had a clash between a match type option and a non-matching
option already, in which it was necessary to choose a new name for the
new option.)
You could even bring back per-handler vars, if you do use -pattern or
something in place of the simple --. And if the -- sentinel is still
allowed as purely optional, then you don't even have the barely
relevant constraint that the handler body it can't be -vars or -pattern,
or a prefix thereof, AND not taking any arguments.
As far as I can tell, that pattern fits EVERYONE's present
requirements, and shouldn't be too much trouble to compile.
As as aside; extending (user-wise) it could be tricky (although I
suspect expanding it efficiently is anyhow), my personal preference
would be for an expansion to return a list with the number of arguments
consumed, and the outcome (whether the body has been evaluated already,
should be evaluated by [try], or didn't match). Failing that, though,
the IMHO ugly [if] syntax will fix that reducing all cases (except
"as" :( ) to merely {handler options body} by grouping everything
between keyword and body in a mandatory list (not so good for
compiling, though, as I understand it). The extensions, I'd suggest,
should either go in a ::tcl::try namespace, or have their own handler
command "with" or something. I like the ::tcl::try namespace better
purely because it's more built-in-friendly. But this whole paragraph
is an issue for another day anyhow.....
--
Fredderic
Debian/unstable (LC#384816) on i686 2.6.23-z2 2007 (up 47 days, 22:12)
|