Perl 6 автоматически вызывает какие-либо специальные методы при очистке объекта?

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

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

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

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


person brian d foy    schedule 13.06.2018    source источник
comment
Джонатан Уортингтон дает подробный ответ в проблеме GitHub, мотивированной этим вопросом: github.com / perl6 / doc / issues / 2097 # issuecomment-396881299   -  person brian d foy    schedule 13.06.2018


Ответы (1)


В 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 ошибается и т. Д. И т. Д.). В чисто многопоточной среде это становится неприемлемым, потому что вам нужно будет выполнять подсчет всех ссылок атомарно (либо с использованием аппаратных функций, либо путем блокировки). Что, помимо общего замедления работы, открывает целый новый пул возможных тупиковых ситуаций.

person Elizabeth Mattijsen    schedule 13.06.2018
comment
Привет, Лиз. В Perl 6 нет надежной доработки объекта. Но есть с вашим модулем FINALIZER, верно? - person raiph; 23.02.2019
comment
В принципе, да, но я не знаю никого, кто действительно пытался бы его использовать, кроме меня, так что это все еще может быть немного грубовато. - person Elizabeth Mattijsen; 23.02.2019