jak*_*kar 9 exception try-catch raku
我们知道故障可以由 CATCH 块处理。
在下面的示例中,我们创建了一个“AdHoc”失败(在其他子中),并在一个 CATCH 块中(在我的子中)处理异常
sub my-sub {
try {
CATCH {
when X::AdHoc { say 'AdHoc Exception handled here'; .resume }
default {say 'Other Exception'; .resume}
}
my $b = other-sub();
$b.so ?? $b.say !! 'This was a Failure'.say;
}
}
sub other-sub { fail 'Failure_X' }
my-sub();
Run Code Online (Sandbox Code Playgroud)
输出如下:
AdHoc Exception handled here
This was a Failure
Run Code Online (Sandbox Code Playgroud)
我的问题是:我们如何区分 CATCH 块中的失败和“正常”异常以区分这两种情况?
Jon*_*ton 12
Failure和之间的关系Exception是 aFailure有一个Exception- 也就是说,它将异常对象作为其状态的一部分。像这样的东西:
class Failure {
has Exception $.exception;
# ...
}
Run Code Online (Sandbox Code Playgroud)
当一个Failure“爆炸”时,它会通过抛出Exception里面的那个来实现。因此,到达CATCH块的是Exception对象,并且没有返回到封闭Failure. (事实上,一个给定的Exception对象原则上可以被许多Failures持有。)
因此,没有直接的方法可以检测到这一点。从设计的角度来看,您可能不应该这样做,而应该找到一种不同的方法来解决您的问题。AFailure只是一种推迟抛出异常并允许将其视为值的方法;根本问题的性质并不打算改变,因为它是作为一个值而不是作为控制流的立即转移来传达的。不幸的是,问题中没有说明最初的目标;您可能会发现查看控件异常很有用,但除此之外,您可能会发布另一个关于您试图解决的潜在问题的问题。可能有更好的方法。
为了完整起见,我会注意到有一些间接的方法可以检测到Exception是由Failure. 例如,如果您获取.backtrace异常对象的 并查看顶部框架的包,则可以确定它来自于Failure:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这在很大程度上取决于可以轻松更改的实现细节,因此我不会依赖它。
只需移除try包装器:
sub my-sub {
# try { <--- remove this line...
CATCH {
when X::AdHoc { say 'AdHoc Exception handled here'; .resume }
default {say 'Other Exception'; .resume}
}
my $b = other-sub();
$b.so ?? $b.say !! 'This was a Failure'.say;
# } <--- ...and this one
}
sub other-sub { fail 'Failure_X' }
my-sub();
Run Code Online (Sandbox Code Playgroud)
你用过try。Atry做了一些事情,但这里的相关事情是它告诉 Raku 立即将Failure其范围内的任何s提升为异常——这就是你所说的你不想要的。所以最简单的解决方案就是停止这样做。
这个答案只是冗长地重复了 jnthn 的部分解释(特别参见他在答案下面写的评论)。但我不相信所有读者都会发现/理解这方面,并且不认为对 jnthn 的回答发表一两条评论会有所帮助,因此这个答案。
我将其写为社区答案,以确保我不会从任何赞成票中受益,因为这显然无法保证。如果它获得足够的反对票,我们将删除它。
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |