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

Re: local $@ has an unwanted side effect

Thread Previous | Thread Next
From:
Yuval Kogman
Date:
March 21, 2008 09:42
Subject:
Re: local $@ has an unwanted side effect
Message ID:
20080321164226.GS19404@woobling.org
On Fri, Mar 21, 2008 at 17:27:04 +0100, Abigail wrote:
> On Fri, Mar 21, 2008 at 05:44:33PM +0200, Yuval Kogman wrote:
> > 	sub foo {
> > 		local $@;
> > 
> > 		eval { # a generic wrapper, doesn'tknow about bar()'s details
> > 			 bar();
> > 		};
> > 
> > 		if ( $@ ) {
> > 			# do something meaningful
> > 			die $@;
> > 		}
> > 	}
> > 
> > 	sub bar {
> > 		die "blah";
> > 	}
> > 
> > 	eval { foo() };
> > 
> > 	warn "Error: $@";
> > 
> > in the 'foo' subroutine $@ is localized to prevent clobbering it in
> > cases such as:
> > 
> > 	eval { ... };
> > 	foo();
> > 	if ( $@ ) { # for the prev eval }
> > 
> > From a control flow POV everything works correctly here, but in the
> > outermost eval { } the value of $@ is not preserved (it will jump
> > though). The value is just ''.
> 
> Well, that's what you want, isn't? In:
> 
>     eval { ... }
>     foo ();
>     if ($@) { ... }
> 
> you want $@ to be the result of the first eval {} (at least, that's what 
> I understand from your comment). How else do you want to achieve that then
> by "ignoring" whatever foo() does with $@?

Umm, that's exactly what foo is trying to achieve with the local, in
an attempt to not interfere with its caller's environment...

> Inspecting $@ to check whether an eval die()d is wrong. It can
> trigger both false positives, and false negatives:

Fair enough, but that goes against the idimatic usage encouraged by
perlfunc which is widely used today.

> But that's how it ought to be done.
> 
> While I agree that people might get bitten by 'local $@' (I have myself),
> it *is* consistent. The eval fails (due to die), which sets $@. Then eval
> is done, after which the scope is exited, triggering DESTROYs, and unrolling
> the effects of local. IMO, you are calling for an exception.

Why? The docs doesn't say this. The fact that die actually sets $@
and not the outer eval { } that does the assignment is not mentioned
or even hinted at in the docs, and there is little benefit from this
behavior.

> But that's what local *IS* all about.

?

> If you don't want the effects of local(), by all means, don't use it.
> Don't make an exception for a specific case. Specially not for a case
> where you were using it wrongly in the first place.

Again, there is no evidence to support that my usage was any more
wrong than the work around is right - I understand how local works,
and I conjectured that die/eval work independently of it, when it is
in fact done by actual assignment. That doesn't mean that my usage
is wrong by design.

-- 
  Yuval Kogman <nothingmuch@woobling.org>
http://nothingmuch.woobling.org  0xEBD27418


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