gpt4 book ai didi

exception - 这个 Perl 6 CATCH block 是否应该能够更改词法范围内的变量?

转载 作者:行者123 更新时间:2023-12-02 11:26:03 24 4
gpt4 key购买 nike

我正在玩可恢复的异常。在这个例子中,我尝试对不进行数字化的东西进行数字化。我发现了这一点,并尝试为 $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.";

CATCH block 可以看到它所在的词法范围,从中断处继续。我希望能够更改 $value 并让 block 的其余部分使用该值,但在 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.

怎么了?

最佳答案

try block 内,use fatal 生效,导致从方法或子调用返回的惰性异常立即抛出。在 try block 的词法范围之外,请注意:

my $value = +$m;

将导致Failure被分配给$valuetry 将它变成了更像这样的东西:

my $value = force-failure(+$m);

你可以想象它被定义为:

sub force-failure(Mu \f) { f.sink if f ~~ Failure; f }

(我挥手是因为编译器吐出代码来内联执行此操作并进行了一些优化)。

在所考虑的情况下,.sink 会触发抛出异常。 CATCH block 运行。 .resume 表明我们不希望像 CATCH block 中通常发生的那样展开调用堆栈,因此在 force-failure 内部继续执行code>,然后返回 f - Failure。这一切都发生在主线代码中分配给 $value 之前;因此分配了 Failure,覆盖 CATCH block 给出的值。

不幸的是,您无法使用 //= 来逃避这一点,因为它会在运行 RHS 之前进行测试(这正是我们通常希望它执行的操作)。但是,可以这样做:

my $numified = +$m;
my $value //= $numified;

当然,这只是一个人为的示例,因为正常的习惯用法是根本没有 try block ,并将其写为:

my $value = +$m // 0;

从而利用失败。一般来说,可恢复异常需要非常小心,因为在许多情况下,不会编写期望发生恢复的代码。事实证明,为致命 Failure 生成的代码就是这样的一段代码。

关于exception - 这个 Perl 6 CATCH block 是否应该能够更改词法范围内的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43289842/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com