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

local $@ has an unwanted side effect

Thread Next
From:
Yuval Kogman
Date:
March 21, 2008 08:44
Subject:
local $@ has an unwanted side effect
Message ID:
20080321154433.GP19404@woobling.org
	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 ''.

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 <nothingmuch@woobling.org>
http://nothingmuch.woobling.org  0xEBD27418


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