From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1263 invoked from network); 3 Oct 2005 17:58:58 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 3 Oct 2005 17:58:58 -0000 Received: (qmail 28474 invoked from network); 3 Oct 2005 17:58:52 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 3 Oct 2005 17:58:52 -0000 Received: (qmail 14179 invoked by alias); 3 Oct 2005 17:58:49 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21816 Received: (qmail 14169 invoked from network); 3 Oct 2005 17:58:48 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 3 Oct 2005 17:58:48 -0000 Received: (qmail 28152 invoked from network); 3 Oct 2005 17:58:48 -0000 Received: from ns9.hostinglmi.net (213.194.149.146) by a.mx.sunsite.dk with SMTP; 3 Oct 2005 17:58:47 -0000 Received: from 212.red-80-35-44.staticip.rima-tde.net ([80.35.44.212] helo=localhost) by ns9.hostinglmi.net with esmtpa (Exim 4.52) id 1EMUaL-0003JW-Ip; Mon, 03 Oct 2005 19:58:45 +0200 Date: Mon, 3 Oct 2005 19:59:13 +0200 From: DervishD To: Bart Schaefer Cc: zsh-workers@sunsite.dk Subject: Re: Exception handling and "trap" vs. TRAPNAL() Message-ID: <20051003175913.GB3231@DervishD> Mail-Followup-To: Bart Schaefer , zsh-workers@sunsite.dk References: <20051001153756.GA12183@DervishD> <1051001183818.ZM27904@candle.brasslantern.com> <20051001202856.GA134@DervishD> <1051002044052.ZM28373@candle.brasslantern.com> <20051002190940.437F9866F@pwstephenson.fsnet.co.uk> <1051002195518.ZM2163@candle.brasslantern.com> <20051002230027.GA194@DervishD> <1051003013758.ZM3107@candle.brasslantern.com> <20051003090121.GC278@DervishD> <1051003162109.ZM4533@candle.brasslantern.com> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1051003162109.ZM4533@candle.brasslantern.com> User-Agent: Mutt/1.4.2.1i Organization: DervishD X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - ns9.hostinglmi.net X-AntiAbuse: Original Domain - sunsite.dk X-AntiAbuse: Originator/Caller UID/GID - [0 0] / [47 12] X-AntiAbuse: Sender Address Domain - dervishd.net X-Source: X-Source-Args: X-Source-Dir: X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 Hi Bart :) * Bart Schaefer dixit: > On Oct 3, 11:01am, DervishD wrote: > } I know, I know, but AFAIK the "always" block works more or less > } the same as exception handling does in other languages. > Less, not more. The problem is that in a language with real > exceptions, the difference between an error and an exception is > well-defined, and it is usually possible to have errors without > exceptions and vice-versa. Zsh's "always" block is an error > handler, not an exception handler, and PWS's functions are > overloading the meaning of "error". But always blocks handle errors that would cause the shell to abort execution. In a certain way, they are exceptions, they're different from errors (with "error" I mean the usual "non-zero exit code"). > } > } Propagating "errflag" may break current code only if that code is > } > } using an inline trap which "returns" a value and that error value is > } > } ignored on purpose. > } > That's not quite correct. Remember, an inline trap using the "return" > } > builtin actually causes the surrounding/calling context to return > } > } That's why I was quoting "return": I didn't mean a literal > } "return" command, but a way of returning a value to the current code. > > Yes, but there *isn't* any way of returning a value to the surrounding > code -- unless you mean something like setting $REPLY. So your basis > for the statement is a practical impossibility. I was thinking exactly that, using $REPLY or something similar. I just wasn't sure if the trap restored all the environment or not. > } But if you propagate the error, you won't break such code. I > } mean, even with your patch, this code... > } > } trap 'readonly VAR; VAR=0' ZERR > } > } print "HERE" > } false > } print "HERE AGAIN" > } > } ...will print both strings. > > In 4.0.6, or with my second potential patch, that prints only "HERE" > (plus the error message about the readonly assignment). In 4.2.5, it > prints both strings. In bash2, it also prints both strings. Anything > that relies on the 4.2.5 or bash2 behavior will break if we go back to > propagating the error as was done in 4.0.6. It doesn't seem to be a good idea, then... > } O:)) As far as I understan, "errflag" just signals the error and > } propagate it to the current execution environment (for inline traps, > } I mean), but doesn't make the shell abort :? > It doesn't make the shell *exit*, but it does stop execution in the > way that would jump into an "always" block. (If it did not, how > would it solve your problem?) In the absence of the "always", it > simply bails out of the current context. The "always" block is a way > to intercept the "bail out" action, but the bail-out happens whether > "always" is there or not. OK, I just was assuming that without the always block the execution would go on undisturbed, which is false. I don't know why I got that false impression, because I really know that code like this: readonly VAR VAR= will stop execution. Sorry, my fault. > } If no patch is applied I can still use TRAPNAL's for throwing > } exceptions, but I must think a way of doing that with inline traps, > } which I think it's impossible because the value of TRY_BLOCK_ERROR is > } reset. > You're right, it's impossible. You'll have to think about how you > would write the code if you never had "always" in the first place, > and write it that way. The problem is that I would like to use "always" blocks with the "nonzeroexitcode" kind of errors (that's why I use ZERR, it helps me to convert the normal errors into errors as defined in a try block context, a condition which causes the shell to stop execution). Obviously this doesn't need nor exceptions nor always blocks, a simple "goto" will suffice because what I want is a way of avoiding handling similar errors in a per-command basis. I mean, I want to replace this code: command1 && {# handle here some possible error probably exiting} command2 && {# handle here exactly the same error as before} ... commandn && {# incredible, here we must handle a similar error} with this one: trap 'throw commonerror$LINENO' ZERR { command1 command2 command3 } always { # Here we catch and handle the common error # In the exception name we have the line number, # just in case we want to fine tune error handling } I face this kind of code frequently: some tightly coupled commands that cause the same kind of errors, or whose failures can be seen as a single error, and execution *must* stop at that point. That's the whole point. I maybe am using the wrong shell construct for solving the problem, and obviously I can always use the first syntax and handle errors one-by-one (and not, something like this: { command1 || command 2 || command 3 } && {#handle error here} won't always work for me), but I find the always block construct much better for this task. If I cannot use the ZERR trap and I must add an explicit throw call after each command, it still is far better than handling the error in place, better even than using a function to handle the error instead of the throw call, because of rethrowing. With all the information you've given to me, I think now that it's not a good idea to patch zsh to alter current behaviour, because I see that current behaviour makes sense, but nonetheless being able to cause 'alwaysable' errors from inline traps looks very good to me O:)) Thanks again for all, Bart. Raúl Núñez de Arenas Coronado -- Linux Registered User 88736 | http://www.dervishd.net http://www.pleyades.net & http://www.gotesdelluna.net It's my PC and I'll cry if I want to...