Первая часть.
А если замыкание используется лишь в самом начале блока, то рациональней сразу после использования освободить ресурсы, а не в конце.
use Carp; sub with_foo { my $foo = shift; my $sub = shift; print "INIT\n"; my $destroyed = 0; my $closure = sub { unless ($destroyed) { $foo += shift; print $foo, "\n"; } else { carp "Already destroyed"; } }; my $destructor = sub { unless ($destroyed) { $destroyed = 1; print "DESTROY\n"; } else { carp "Already destroyed"; } }; eval { $sub->($closure, $destructor) }; $destructor->() unless $destroyed; } { with_foo(3, sub { my ($foo, $_foo) = @_; $foo->(1); $foo->(1); $foo->(2); $foo->(2); $_foo->(); print "END\n" }); }