我滚动浏览 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 $!,我们是否也不必本地化$??