Периодически ловил себя на мысли, что хорошо бы, чтобы у замыканий были дестркторы.
И лишь вчера осознал, что это можно легко организовать "вывернув" замыкания на изнанку.
Рассмотрим в качестве примера следующий код:
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); }); }