Perl 6 在清理对象时会自动调用任何特殊方法吗?

Does Perl 6 automatically call any special methods when it cleans up an object?

我以为 Rakudo 几年前就获得了终结器支持,但我找不到它的文档(也许它在 Classes and Objects 中)。在 class 中列出所有方法似乎不是我要找的东西。

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

也许问题是#127243: [RFC] DESTROY is not called on interpreter exit

啊,在roast/S12-construction/destruction.t中标记为"to do"。

Perl 6 中没有可靠的 对象终结。支持DESTROY,但只有在对象实际被垃圾回收时才会调用它。垃圾收集 不会 在全局关闭时发生,但在需要时(根据它决定的任何启发式方法)。

以下代码显示 对象被垃圾收集时,它们调用 DESTROY:

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

通常会输出如下内容:"DESTROY called 31095 times".

如果你想要可靠的破坏,你可以使用 LEAVE 相位器,或者 will leave 特性:

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

或更短:

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

应该意识到允许可靠销毁的引用计数有其问题(循环引用,因此您需要弱引用,共享内存的取消共享,因为它需要更新计数器,XS 代码出错,等等。 ETC。)。在纯线程环境中,这变得站不住脚,因为您需要以原子方式执行所有引用计数(通过使用硬件功能或通过锁定)。这除了通常会减慢速度之外,还会打开一个全新的可能死锁池。