我有一段类似于以下的 Perl 代码(非常简化): 有一些级别的嵌套子例程调用(实际上是方法),一些内部的调用自己的异常处理:
sub outer { middle() }
sub middle {
eval { inner() };
if ( my $x = $@ ) { # caught exception
if (ref $x eq 'ARRAY') {
print "we can handle this ...";
}
else {
die $x; # rethrow
}
}
}
sub inner { die "OH NOES!" }
现在我想更改该代码,使其执行以下操作:
为每个“冒泡”到最外层 (
sub outer
) 的异常打印完整的堆栈跟踪。具体来说,堆栈跟踪不应停止在“eval { }
”的第一级。不必更改任何内部级别的执行。
现在,我这样做的方法是在sub中安装一个本地化__DIE__
处理程序:outer
use Devel::StackTrace;
sub outer {
local $SIG{__DIE__} = sub {
my $error = shift;
my $trace = Devel::StackTrace->new;
print "Error: $error\n",
"Stack Trace:\n",
$trace->as_string;
};
middle();
}
[编辑:我犯了一个错误,上面的代码实际上并没有按照我想要的方式工作,它实际上绕过了middle
sub 的异常处理。所以我想问题应该是:我想要的行为是否可能?]
这完美地工作,唯一的问题是,如果我正确理解文档,它依赖于明确弃用的行为,即__DIE__
处理程序被触发的事实,即使是 " die
"s 内部的 " eval { }
"s,他们真的不应该这样做。两者都perlvar
声明perlsub
这种行为可能会在 Perl 的未来版本中被删除。
有没有另一种方法可以在不依赖已弃用的行为的情况下实现这一目标,或者即使文档另有说明也可以节省依赖?