Периодически ловил себя на мысли, что хорошо бы, чтобы у замыканий были дестркторы.
И лишь вчера осознал, что это можно легко организовать "вывернув" замыкания на изнанку.
Рассмотрим в качестве примера следующий код:
sub make_foo {
my $foo = shift;
print "INIT\n";
return sub {
$foo += shift;
print $foo, "\n";
};
}
{
my $foo = make_foo(3);
$foo->(1);
$foo->(1);
$foo->(2);
$foo->(2);
}
А теперь сделаем так, что замыкание не возвращается в функцию с действием, а передается ей в качестве аргумента.
Это позволяет добавить деструктор сразу после вызова этой функции:
sub with_foo {
my $foo = shift;
my $sub = shift;
print "INIT\n";
$sub->(sub {
$foo += shift;
print $foo, "\n";
});
print "DESTROY\n";
}
{
with_foo(3, sub {
my $foo = shift;
$foo->(1);
$foo->(1);
$foo->(2);
$foo->(2);
});
}