develooper Front page | perl.perl5.porters | Postings from May 2010

Re: more reliable exception handling

Thread Previous | Thread Next
From:
Rafael Garcia-Suarez
Date:
May 4, 2010 14:16
Subject:
Re: more reliable exception handling
Message ID:
v2nb77c1dce1005041416q75c38d77me1e9305fcc9d142@mail.gmail.com
Thanks for the detailed wrap up. Comments follow.

(I would have to add that I don't consider the breakage of safesort.t
as a breakage : previously we had a message duplicated, as an
exception and as a warning, now it's only a warning. I'm not exactly
sure what happens there yet, given the intrication of closures, evals,
and revals, but it looks like a step in the good direction at least.)

On 4 May 2010 22:29, Zefram <zefram@fysh.org> wrote:
[...]
> Jesse asked about the Perl-visible changes resulting from my patches.
> In the following list I'm trying to be complete, at the expense of having
> some of the list entries overlap.  Single implementation changes tend
> to have multiple results around here, and there are multiple ways to
> encounter some of the effects.
>
>    * Where an exception is thrown, code running early in the throwing
>      process (e.g., in &{$SIG{__DIE__}}) will now see a consistent
>      behaviour for the contents of $@, where previously the behaviour
>      differed depending on whether the exception was a string or not.
>      Previously, a non-string exception would appear in $@, but a string
>      exception would leave the former value of $@ unchanged.  Now $@
>      will be unchanged at this point in either case.  (Note that the
>      exception being thrown is properly presented to &{$SIG{__DIE__}}
>      as a parameter, and this part is *not* changing.)
>
>    * Where an exception is thrown, and code running early in the
>      throwing process (e.g., in &{$SIG{__DIE__}}) writes to $@ (by
>      assignment or internal eval), this will not affect the exception
>      being thrown, where previously it sometimes would.  To be precise,
>      previously, a write to $@ at this point would replace the exception
>      being thrown, iff the exception originally being thrown was
>      a non-string.  (This opportunity to clobber occurs in exactly
>      the same circumstances as the visibility of the exception in $@
>      discussed in the previous item.)
>
>    * Where an exception is thrown, code running during unwinding (e.g.,
>      destructors) will see $@ containing its former contents, where
>      previously it would see the exception being thrown.
>
>    * Where an exception is thrown, and code running during unwinding
>      (e.g., destructors) writes to $@ (by assignment or internal eval),
>      this will not affect the exception being thrown, where previously
>      it would replace the exception being thrown.

This is a most prominent problem many times discussed here. I'm happy
to see it going away.

>    * Where $@ is local()ised inside an eval, this will not affect
>      exception throwing for that eval, where previously the restoration
>      of $@ would clobber any exception being thrown.  This is a special
>      case of the previous item.
>
>    * Where Perl-level warn() is called with a single non-string argument
>      (i.e., a structured warning object), &{$SIG{__WARN__}} will be
>      passed the object itself, where previously it was passed the result
>      of stringifying the object.
>
>    * Where Perl-level warn() is called with no arguments, thus picking
>      up the thing to warn about from $@, and $@ holds a non-string
>      exception, the exception will be used as-is, where previously it
>      was stringified and had text appended to it.
>
>    * Where code is called with G_KEEPERR (e.g., a DESTROY method) and
>      throws a string exception, and the ambient value of $@ is a string,
>      the ambient $@ will remain unchanged, where previously the inner
>      exception was appended to it.

I remember that is was suggested to use @@ to accumulate such
exceptions (in addition of the change you implemented.) (likewise for
the following cases)

>    * Where code is called with G_KEEPERR (e.g., a DESTROY method) and
>      throws an exception, and the ambient value of $@ is not a string,
>      the ambient $@ will remain unchanged, where previously the inner
>      exception replaced it.
>
>    * Where code is called with G_KEEPERR (e.g., a DESTROY method)
>      and throws a string exception, and a string-identical exception
>      was recently thrown by G_KEEPERRed code called by the same outer
>      code, the repeat exception will result in a repeat warning, where
>      previously the warning was suppressed.
>
>    * Where code is called with G_KEEPERR (e.g., a DESTROY method) and
>      throws a non-string exception, the ambient $@ will remain unchanged,
>      where previously the inner exception replaced it.
>
>    * Where code is called with G_KEEPERR (e.g., a DESTROY method)
>      and throws a non-string exception, the exception will be emitted
>      as a warning (just like a string exception), where previously no
>      warning was generated.
>
> Looking back at the list, this is potentially a monster perldelta entry.
> But it reduces the complexity of the exception behaviour, as you can in
> part see by the shortening of the L<perlcall> segment.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About