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

local $@ has an unwanted side effect

Thread Next
Yuval Kogman
March 21, 2008 08:44
local $@ has an unwanted side effect
Message ID:
	sub foo {
		local $@;

		eval { # a generic wrapper, doesn'tknow about bar()'s details

		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 { ... };
	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 ''.

Since there is no other way to know if the eval actually failed
without inspecting $@ that makes it faily useless, and furthermore
the documentation of eval implies this should not be the case (but
doesn't mention local).

I believe this is an implementation detail, likely die() in the
context of an eval assigning to $@ with it's localization stack,
instead of the assignment happenning in the scope of the eval { }
that is actually trapping the error, so in effect the error that it
trapped is in $@.

The work around is in foo():

	sub foo {
		my $e;
			local $@;
			eval { bar () };
			$e = $@;

		if ( $e ) { die $e }

but that kinda sucks.

Every time this happenned to me it took a really long while to
figure out, a conservative guess is that I've lost about 2-3 days of
my life to this behavior over the past few years. This is because
it's action at a distance on several levels.

  Yuval Kogman <>  0xEBD27418

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About