Первая часть.
А если замыкание используется лишь в самом начале блока, то рациональней сразу после использования освободить ресурсы, а не в конце.
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"
});
}