* John Siracusa <siracusa@gmail.com> [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. Regards, -- Aristotle Pagaltzis // <http://plasmasturm.org/>Thread Previous | Thread Next