控制还是一旦与最后一团糟?

jjm*_*elo 5 exception perl6

此循环永不停止:

class CX::Vaya does X::Control {
    has $.message
}

loop {
    once {
        CX::Vaya.new( message => "I messed up!" ).throw;
    }
    last;
    CONTROL {
        default {
            say "Controlled { .^name }: { .message }"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它一直在写

Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
Controlled CX::Last: <last control exception>
...
Run Code Online (Sandbox Code Playgroud)

可能once有点,因为最后一个CONTROL移相器确实完成了:

loop { say "Hey"; last; CONTROL { default: .message.say } }
# OUTPUT: «Hey?<last control exception>?»
Run Code Online (Sandbox Code Playgroud)

但是我不确定。

Jon*_*ton 13

Perl 6中的循环流控制是使用控制异常实现的。因此,last实际上是引发了CX::Last控制异常。由于该CONTROL块使用default,因此它捕获了CX::Lastthrow last,这意味着控制永远不会移出循环。

解决方法是改为使用来指定要捕获的控件异常when

loop {
    once {
        CX::Vaya.new( message => "I messed up!" ).throw;
    }
    last;
    CONTROL {
        when CX::Vaya {
            say "Controlled { .^name }: { .message }"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


rai*_*iph 7

乔纳森说什么。

更详细地:

  • P6的默认控制流程是,下一条语句将紧随当前语句。因此,say 42; say 99;默认情况下先执行say 42,然后再执行say 99

  • P6具有先进且广泛使用的异常系统,该系统用于处理此一语句的默认控制流的异常,然后立即执行以下语句。这不仅仅是错误。

  • 默认控制流的任何异常都称为异常。许多是错误异常。但是还有另一类,即控制流异常或简称控制异常。例如,来自例程/块的显式或隐式return/ leave是控制异常。(原则上。实际上,编译器/优化器会在适当的情况下忽略某些这种机制。)

  • A last是控件异常。它引发控制异常CX::Last。其消息有效载荷为"last control exception"。您正在看到该消息。

  • CONTROL如果控制异常适用于它的包含块被输入块。它可以处理传递的异常,也可以不处理。如果处理,则控制将继续执行其后的语句。如本例所示,如果该CONTROL块位于循环的末尾,则下一条语句将是隐式的next(另一个控制异常),并且循环将重新开始。

  • 该代码CONTROL { default { say "Controlled { .^name }: { .message }" }处理所有控制异常,包括由引发的异常last。因此它将打印其消息,然后循环继续。(无限地。)

  • 在代码中loop { say "Hey"; last; CONTROL { default: .message.say } } # OUTPUT: «Hey?<last control exception>?»,该CONTROL块的确显示了异常的消息,但没有处理。(default:只是一个标签,I'm-a-label:与之没有区别,并且与不相关default { ... }。)因此,last控制异常不是由您的代码处理,而是由打破循环的默认语言处理来处理。