perl - 在 Test::More 中的 eval 期间保护全局变量

标签 perl error-handling eval test-more

我滚动浏览 Test::More 的代码,因为我想看看 use_okrequire_ok已实现(以及为什么 Ovid 不喜欢它们)。我来到了 _eval 子程序,其中包含一些我不完全理解的特殊逻辑,用于在 eval 期间保护变量称呼。我从 Try::Tiny 的文档中了解到处理有多么困难$@ .但是,我不明白 $! 的处理方式和 $SIG{__DIE__} (以下 block 逐字复制):

# 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 相关,但我还是不明白。为什么有必要在最后一行再次设置变量,因为它应该总是在 block 的最后一行设置?如果这些行的全部目的是将变量设置为 eval 中的任何内容调用,为什么必须首先本地化?

此外,如果使用 eval没有破坏错误变量意味着本地化 $@$! ,我们是否也必须本地化 $? ?

最佳答案

在我看来它像 $sigdie是否有明确允许评估代码设置$SIG{__DIE__} ,同时不允许任何外部设置的处理程序在评估期间生效。

因此本地化抑制了外部值,但需要在 block 结束之前保存任何设置值,并在 block 之后将其设置为现在未本地化的版本。

我假设 $!已本地化但不是 $? , $^E等出于实际原因(也就是说,我猜人们提示 $! 更改,但没有其他任何东西)。

关于perl - 在 Test::More 中的 eval 期间保护全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20981861/

相关文章:

没有 Eval 的 PHP 动态鸭子类型(duck typing)

regex - Perl-regex 在应该区分大小写时不区分大小写

perl - 在 Perl 中绑定(bind)运算符意味着什么?

windows - perl中的无缓冲IO

apache - Apache 中的 "End of script output before headers"错误

azure - 在Windows Azure IIS上重定向Joomla错误

javascript - 不使用 Eval 动态引用 Javascript 数组名称?

c# - Entity Framework : how to catch any error

powershell - ErrorVariable无法使用null或空参数

ruby - 试图找到 : . (eval):289 的文件/行:警告:不要在参数括号前放置空格