我应该在哪里捕获Perl 6警告控制异常?

bri*_*foy 7 warnings exception perl6

我正在玩Perl 6的控制异常.甲警告引发一个例外控制其是不可见的正常的异常控制流程图,并且该异常恢复本身.那有点酷.

所以,玩这个,我写这个看看会发生什么.除了看到Perl 6实际上做了什么之外,我不是想解决一个特定的问题:

use v6;

try {
    CONTROL {
        put "Caught an exception, in the try";
        put .^name;
        }
    do-that-thing-you-do();
    }

sub do-that-thing-you-do {
    CONTROL {
        put "Caught an exception, in the sub";
        put .^name;
        }
    warn "This is a warning";
    }
Run Code Online (Sandbox Code Playgroud)

它看起来像两个火:

Caught an exception, in the sub
CX::Warn
Caught an exception, in the try
CX::Warn
This is a warning
  in sub do-that-thing-you-do at resume.p6 line 16
MoarVM panic: Trying to unwind over wrong handler
Run Code Online (Sandbox Code Playgroud)

请注意,有一个Moar恐慌,我提出了一个问题.但是,我并不是真的在问这个问题.

我对这里流动的图片感到好奇.我期望CONTROLsub 中的a 会捕获异常并恢复,所以它不会渗透到try.应该如何流动?

另外,请注意例外情况CX::Warn.我不认为我在那里做了一些奇怪的事情,但Perl 6类型甚至没有列出X::Warn

Jon*_*ton 6

要获得与默认警告处理程序相同的行为,则必须同时捕获异常(如同CATCH,CONTROL没有智能匹配将重新抛出)以及resume之后.

CONTROL {
    when CX::Warn {
        say "Warning: $_";
        .resume
    }
}

sub foo() {
    say 1;
    warn 'oh gosh...';
    say 2;               # Not reached without .resume
}
foo();
Run Code Online (Sandbox Code Playgroud)

还有许多其他控制异常,因此仅匹配CX::Warn而不是使用是明智的default.否则take,next,last,emit,done(并且,在6.D,大概也await)可以通过您的处理程序,这将肯定会使相当长的一段头痛被捕.