develooper Front page | perl.perl5.porters | Postings from March 2008

Re: local $@ has an unwanted side effect

Thread Previous | Thread Next
From:
David Nicol
Date:
March 21, 2008 10:56
Subject:
Re: local $@ has an unwanted side effect
Message ID:
934f64a20803211056q5148027ava77af36f51c96418@mail.gmail.com
On Fri, Mar 21, 2008 at 12:03 PM, Abigail <abigail@abigail.be> wrote:

>  Now, I'm getting confused. To me it seems you are saying that you are
>  using 'local $@' inside 'foo' as to not clobber an outside $@, and then
>  you're complaining that $@ isn't set when returning from 'foo'. You can't
>  have it both ways.

The OP's example is too long.  He wants to hide $@, but set it again in
certain circumstances, without using intermediate variables. (which will make
his code that does this not work with "older" perls if the change
would get made)

$ perl -le 'sub localdie { local $@; die "DIED\n" }; eval {
localdie(); }; print $@||"cleared\n"'
cleared

$ perl -le 'sub localdie { { local $@; }; die "DIED\n" }; eval {
localdie(); }; print $@||"cleared\n"'
DIED

Ths issue is that in the first case, the assignment to $@, which is
supposed to happen
by the eval, is affected by the local within localdie, which should
have been completed
before eval sets $@.

How can this be documented?

$ diff -u  /usr/lib/perl5/5.8/pods/perlfunc.pod.orig
/usr/lib/perl5/5.8/pods/perlfunc.pod
--- /usr/lib/perl5/5.8/pods/perlfunc.pod.orig   2008-03-21
12:36:39.263371300 -0500
+++ /usr/lib/perl5/5.8/pods/perlfunc.pod        2008-03-21
12:53:19.812144700 -0500
@@ -1568,6 +1568,22 @@
 particular situation, you can just use symbolic references instead, as
 in case 6.

+The assignment to C<$@> occurs before restoration of localised variables,
+which means a temporary is required to mask some but not all errors:
+
+    # alter $@ on nefarious repugnancy only
+    {
+       my $e;
+       {
+          local $@;  # hide outer $@
+          eval { test_repugnancy() };
+          # $@ =~ /nefarious/ and die $@; # DOES NOT WORK
+          $@ =~ /nefarious/ and $e = $@;
+       }
+       die $e if defined $e
+    }
+
+
 C<eval BLOCK> does I<not> count as a loop, so the loop control statements
 C<next>, C<last>, or C<redo> cannot be used to leave or restart the block.

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