2017-04-05 46 views
5

我在玩Perl 6的控件异常。 A warn引发了对正常异常控制流不可见的控制异常,并且该异常自行恢复。这有点酷。所以,玩了这个,我写了这个看看会发生什么。我并不想解决不是看到什么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"; 
    } 

它看起来既像火:

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 

注意有一个Moar恐慌,这I've raise an issue for。但是,我并没有真的在问这个问题。

我很好奇这里的流程图。我预计子中的CONTROL会捕获异常并恢复,因此它不会渗透到try。该如何流动?

另外,请注意例外情况是CX::Warn。我不认为我做了一个奇怪的现象出现,但Perl 6 types却连列表X::Warn

+0

请注意,整个'CX ::'命名空间没有记录在该页面上...... – Christoph

+1

请在https://github.com/perl6/doc中添加一个缺少文档的问题。谢谢! –

+0

文档问题:https://github.com/perl6/doc/issues/1268 –

回答

5

要获得相同的行为作为默认的警告处理,那么它必须既捕捉到了异常(如CATCH,没有智能匹配的CONTROL将重新投掷),并且在其之后也将变为resume

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

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

还有许多其他的控制异常,因此它是明智的,只有匹配CX::Warn而不是使用default。否则,take,next,last,emit,done(并且在6.d中,可能还有await)可能被你的处理程序捕获,这肯定会造成一些头疼的问题。

相关问题