【发布时间】:2014-01-25 17:44:59
【问题描述】:
我滚动浏览了 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 而不破坏错误变量意味着本地化 $@ 和 $!,我们是否也不必本地化 $??
【问题讨论】:
标签: perl error-handling eval test-more