我正在玩可恢复的例外.在这个例子中,我尝试编号不编号的东西.我抓住了它并尝试给$value变量一个合适的值然后恢复执行:
try {
my $m = 'Hello';
my $value;
$value = +$m;
put "Outside value is ?{$value.^name}?";
CATCH {
when X::Str::Numeric {
put "?$m? isn't a number!";
put "Inside value is ?{$value.^name}?";
$value = 0;
put "Inside value is now ?$value.?";
.resume;
}
default {
put "Unhandled type ?{.^name}?";
}
}
put "End of the block";
}
put "Got to the end.";
Run Code Online (Sandbox Code Playgroud)
该CATCH块可以看到它所处的词法范围,一个恢复从它停止的地方开始.我希望我能够更改$value并让其余的块使用该值,但在CATCH该值之外变为失败:
?Hello? isn't a number!
Inside value is ?Any?
Inside value is now ?0.?
Outside value is ?Failure?
End of the block
Got to the end.
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
在try块内部use fatal生效,导致从方法或子调用返回的延迟异常立即抛出.在try块的词法范围之外,请注意:
my $value = +$m;
Run Code Online (Sandbox Code Playgroud)
会导致Failure被分配到$value.将try它变成更多的东西一样:
my $value = force-failure(+$m);
Run Code Online (Sandbox Code Playgroud)
你可以想象被定义为:
sub force-failure(Mu \f) { f.sink if f ~~ Failure; f }
Run Code Online (Sandbox Code Playgroud)
(我正在挥手,因为编译器吐出代码来内联并进行一些优化).
在考虑的情况下,.sink触发抛出的异常.该CATCH块运行.这.resume表明我们不希望像CATCH块通常发生的那样解开调用堆栈,因此内部继续执行force-failure,然后返回f- Failure.这一切都发生在主线代码中的赋值之前$value; 将Failure因此被认为是,覆盖由给定的值CATCH的块.
不幸的是,你无法逃避这一点,//=因为它在运行RHS之前进行了测试(这是我们通常希望它做的).但是,有可能做到:
my $numified = +$m;
my $value //= $numified;
Run Code Online (Sandbox Code Playgroud)
当然,这只是一个人为的例子,因为正常的习惯用法是根本没有try块,并把它写成:
my $value = +$m // 0;
Run Code Online (Sandbox Code Playgroud)
因此利用了Failure.通常,可恢复的异常需要大量的注意,因为在许多情况下,代码将不会被写入,期望恢复发生.事实证明,为致命a Failure而生成的代码就是这样一个.
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |