我滚动浏览 Test::More 的代码,因为我想看看是如何实现的(use_ok
以及require_ok
为什么 Ovid 不喜欢它们)。我来到了_eval
子例程,其中包含一些我不完全理解的特殊逻辑,用于在eval
调用期间保护变量。我从Try::Tiny的文档中了解到处理$@
. 但是,我不明白和的处理$!
($SIG{__DIE__}
下面逐字复制块):
# Work around oddities surrounding resetting of $@ by immediately
# storing it.
my( $sigdie, $eval_result, $eval_error );
{
local( $@, $!, $SIG{__DIE__} ); # isolate eval
$eval_result = eval $code; ## no critic (BuiltinFunctions::ProhibitStringyEval)
$eval_error = $@;
$sigdie = $SIG{__DIE__} || undef;
}
# make sure that $code got a chance to set $SIG{__DIE__}
$SIG{__DIE__} = $sigdie if defined $sigdie;
的处理$SIG{__DIE__}
与RT #34065有关,但我仍然不明白。为什么有必要在最后一行再次设置变量,因为它应该总是在块的最后一行设置?如果这些行的全部目的是将变量设置为eval
调用中的任何内容,那么为什么必须首先将其本地化?
另外,如果使用eval
不破坏错误变量意味着本地化$@
and $!
,我们是否也不必本地化$?
?