代码之家  ›  专栏  ›  技术社区  ›  brian d foy

Perl6在清理对象时是否自动调用任何特殊方法?

  •  11
  • brian d foy  · 技术社区  · 8 年前

    几年前我还以为Rakudo得到了最后定稿人的支持,但我找不到它的文档(也许它会进入 Classes and Objects )。在一个类中列出所有方法似乎不像我要查找的那样。

    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 .

    1 回复  |  直到 7 年前
        1
  •  12
  •   Elizabeth Mattijsen    8 年前

    没有 可靠的 Perl6中的对象终结。有人支持 DESTROY ,但只有在对象实际被垃圾收集时才会调用它。垃圾收集可以 不 在全局关闭时发生,但在需要时(从任何启发式方法中,它都决定了这一点)。

    下面的代码显示 什么时候 对象被垃圾收集,它们调用 销毁 以下内容:

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

    它通常会输出类似“破坏31095次”。

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

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

    或更短:

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

    应该认识到,允许可靠销毁的引用计数有其问题(循环引用,因此需要弱引用、共享内存因为需要更新计数器而取消共享、XS代码出错等)。在纯线程环境中,这变得不可维持,因为您需要原子地进行所有引用计数(通过使用硬件功能或通过锁定)。这除了通常会减慢速度外,还为可能出现的僵局打开了一个全新的水池。