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

Re: Confused by eval behavior

Thread Previous | Thread Next
Aristotle Pagaltzis
June 23, 2016 17:17
Re: Confused by eval behavior
Message ID:
* John Siracusa <> [2016-06-23 18:24]:
> eval {
> my $foo = Foo->new;
> };
> ok(!$@, 'exception handled in destructor (no extra final statement in eval)');

This one fails because there isn’t any exception during the eval. So the
Foo instance is returned as the value of the `eval` block. If you put
a `warn` in front of the `eval` you can see that. Then at the end of the
statement the Foo instance goes out of scope and only at that point does
its DESTROY fire.

So the $@ declobbering change is in fact irrelevant to the behaviour of
this particular test.

> eval {
> my $foo = Foo->new;
> die ($foo = 'Died in eval');
> };
> like($@, qr/^Died in eval/, 'exception thrown in eval (object destroyed in last statement)');

This can be provoked into failing in the same way by various alternate
phrasings such as

    $foo = 1, die 'Died in eval';

The key is to put $foo on the stack, then overwrite it. The result as
best as I can surmise from my not-actually-a-guts-hacker understanding
is that when $foo goes out of scope, it is no longer pointing to the Foo
instance, which therefore survives until the end of the statement… which
once again is outside the `eval` block, and therefore clears the hurdle.

Basically, the specifics of the timing of how far things survive when it
comes to the last statement of a block are fiddly and you must carefully
control what the last statement is and what it does to avoid surprises.

Aristotle Pagaltzis // <>

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