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

my $@ - a proposal

Thread Next
From:
Yuval Kogman
Date:
June 27, 2008 00:39
Subject:
my $@ - a proposal
Message ID:
20080627073939.GU23537@woobling.org
For reasons previously discussed, this code is broken:

	eval { this_may_die };
	die $@ if $@;

(it clears the previous value of $@ if there is an error).

This is not a solution:

	local $@;
	eval { this_may_die };
	die $@ if $@;

(it never sets an outer $@ in the die $@ if $@ code, because
unlocalization will clear $@ after the current scope is left via the
die).

On a related note, this code is also broken:

	sub DESTROY {
		eval { }
	}

Because of:
	
	{
		my $obj = ...;
		eval { };
	}

	# $@ has been cleared by $obj's DESTROY here



One possible solution is the addition of an optional lexical $@

When entering an eval { } if a lexical $@ is in scope then this will
be set as the place to write errors to, otherwise the global $@ is
used (as is currently the case).

An exception inside the eval { } (no matter how deep within the
lexical scope) that will exit this particular eval will thus always
write to the lexical $@ associated with that eval.

die $@ will also work because it will set the $@ for the outer eval
{ } (if any), which the same lexical, a different lexical, or global
$@.

Using

	sub DESTROY {
		my $@;
		eval { }
	}

or using my $@ in your own code will solve the DESTROY brokenness.

What is not solved is

	sub DESTROY {
		my $@;
		shift->foo();
	}

	sub foo { eval { } }

I don't have an idea for solving DESTROY in all cases.

-- 
  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