Perl 6 автоматически вызывает какие-либо специальные методы, когда очищает объект? - PullRequest
0 голосов
/ 13 июня 2018

Я думал, что Rakudo получил поддержку финализатора несколько лет назад, но я не смог найти документацию для него (возможно, это входит в Классы и объекты ).Перечисление всех методов в классе не похоже на то, что я искал.

class Butterfly {
    method DESTROY { put "Destroyed" }
    # submethod DESTROY { put "Destroyed" }
    }
{
Butterfly.new;
}

Возможно, проблема в # 127243: [RFC] DESTROY не вызывается при выходе из интерпретатора

Ах, и помечено как "сделать" в roast / S12-construction / destroy.t .

1 Ответ

0 голосов
/ 13 июня 2018

В Perl 6 отсутствует надежное завершение объекта. Существует поддержка DESTROY, но она будет вызываться только тогда, когда объект фактически собирается сборщиком мусора.Сборка мусора не происходит при глобальном отключении, но когда это необходимо (исходя из эвристических соображений, которые это решают).

Следующий код показывает, что , когда объекты получают мусорсобранные, они вызывают DESTROY:

my int $destroyed;
class A {
    method DESTROY { ++$seen }
}
A.new for ^50000;
say "DESTROY called $destroyed times";

, который обычно выводит что-то вроде: «DESTROY вызывается 31095 раз».

Если вы хотите надежного уничтожения, вы можете использовать LEAVE фазерыили will leave признак:

my $dbh = DBI.connect(....);
LEAVE $dbh.disconnect;

или короче:

my $foo will leave { say "left with $_" } = 42;
# left with 42

Следует понимать, что подсчет ссылок, который обеспечивает надежное уничтожение, имеет свои проблемы (круговые ссылки, таквам нужны слабые ссылки, разделение общей памяти, потому что нужно обновить счетчики, неправильно понять код XS и т. д. и т. д.).В чисто многопоточной среде это становится неприемлемым, потому что вам нужно будет делать все подсчеты ссылок атомарно (либо с помощью аппаратных функций, либо с помощью блокировки).Что, помимо общего замедления, открывает целый ряд возможных тупиков.

...