пятница, 25 мая 2012 г.

Деструкторы для замыканий

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

1 комментарий:

Анонимный комментирует...

Ну это как-то не то по синтаксису.
Я бы Guard'ом воспользовался: https://gist.github.com/2793574