假设我有一个模块Bar,它是模块Foo的子类包装器.我希望调用Bar的方法来模仿Foo - 甚至是致命的错误.到目前为止,很容易; 我只是称之为SUPER方法.
sub stuff {
# Do stuff here
SUPER::stuff(@_);
# Do more stuff here
}
Run Code Online (Sandbox Code Playgroud)
但是,让我们说我想抓住,记录并重新抛出任何致命的错误SUPER::stuff()
.前两个步骤很简单:
sub stuff {
# Do stuff here
eval {
SUPER::stuff(@_);
};
$@ and log("Naughty, naughty: $@");
# Do more stuff here
}
Run Code Online (Sandbox Code Playgroud)
......但我不知道怎么做最后一部分.如何以这样一种方式重新抛出错误,即调用者无法区分调用Foo->stuff()
和调用Bar->stuff()
?我可以die $@
在日志声明之后插入并期望它能够做我想要的,或者这里有细微差别可能会让我遇到麻烦吗?
在Perl中安全地eval/catch/log/rethrow的完整代码可能有点冗长.
sub stuff {
# Do stuff here
local $@; # don't reset $@ for our caller.
my $eval_ok = eval { # get the return from eval, it will be undef if the eval catches an error.
SUPER::stuff(@_);
1; # return 1 (true) if there are no errors caught.
};
if (!$eval_ok) { # don't trust $@ it might have been reset as the eval unrolled.
my $error = $@ || 'unknown error'; # copy $@ incase write_log resets $@, or is later changed to cause it to reset $@.
write_log("Naughty, naughty: $error");
die $error; # after all that we can rethrow our error.
}
# Do more stuff here
}
Run Code Online (Sandbox Code Playgroud)
您可以使用尝试::微小的暴徒sugested简化:
sub stuff {
# Do stuff here
try {
SUPER::stuff(@_);
} catch {
my $error = $_;
write_log("Naughty, naughty: $error");
die $error;
}
# Do more stuff here
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1962 次 |
最近记录: |