我正在玩可恢复的例外.在这个例子中,我尝试编号不编号的东西.我抓住了它并尝试给$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 次 |
最近记录: |