Perl 的 $@ 在 eval 之后会变得未定义吗?

问题描述 投票:0回答:4

我正在研究掌握 Perl“错误处理和报告”章节。在 perlvar

$@
条目中,它说:

来自最后一个 eval() 运算符的 Perl 语法错误消息。如果 $@ 是空字符串,则最后一个 eval() 会正确解析并执行(尽管您调用的操作可能以正常方式失败)。

现在我想知道 eval 何时可能无法正确执行,从而使

$@
具有未定义的值。有这样的案例吗?

perl eval
4个回答
4
投票

这是一种方法(但在阅读之前请坐下。;))

$@ = 123;
eval q{
  $@ = 456;
  print ">>>$@<<<\n";
  goto SKIP;
};

SKIP:
print ">>>$@<<<\n";

3
投票

Try::Tiny 文档BACKGROUND 部分包含一些有关如何破坏

$@
以及为什么 Try::Tiny 特别注意避免破坏的信息,并且始终测试
eval
的返回值而不是测试
$@
为了真理。他们所有人都在那里,因为某人在某个时候遇到了他们,但我认为
eval
-in-
DESTROY
的场景是最有可能绊倒某人的。基本上,如果
die
导致某个对象超出范围,并且该对象有一个
DESTROY
调用
eval
,那么您最初使用
die
的值将无法挽回地丢失。假设
eval
中的
DESTROY
抛出错误,$@
 将是 
""
 跟随外部 
eval


1
投票
谁说过关于将

$@

 设置为 undef 的事?

“最后一个 eval() 正确解析并执行”没有任何意义:

eval

在运行时不被解析。当然,它的意思是“最后一个表达式被正确解析和执行的 eval()”。换句话说,“最后一个 eval() 的表达式已编译并且在执行时没有抛出任何异常”。

>perl -MData::Dumper -e"$@=123; eval ''; print(Dumper($@));" $VAR1 = ''; >perl -MData::Dumper -e"$@=123; eval '~~~'; print(Dumper($@));" $VAR1 = 'syntax error at (eval 1) line 2, at EOF '; >perl -MData::Dumper -e"$@=123; eval 'die q{x}'; print(Dumper($@));" $VAR1 = 'x at (eval 1) line 1. ';
    

0
投票
如果有人读了这个问题并且仍然想知道(就像我一样)

$@

eval
之后是否可以未定义,我相信答案是否定的。 (我还在 $@
的旧 5.8.3 文档中读到它是“null”,我很困惑,因为“null”不是 Perl 中经常使用的术语。) 我不了解 Perl 内部知识来确认这一点,但看起来文档最终在 2015 年通过

this commit

修复,这是由于 this 问题 产生的。 perlvar 的条目 现在显示“空字符串”而不是“null”:

来自最后一个“eval”运算符的 Perl 错误,即捕获的最后一个异常。对于“eval BLOCK”,这要么是运行时错误消息,要么是调用“die”时使用的字符串或引用。 “eval STRING”形式还可以捕获语法错误和其他编译时异常。

如果没有错误发生,“eval”将 $@ 设置为空字符串。

此外,鉴于 $@ 可以设置为“调用模具的字符串或引用模具”,我想我会确保
die undef

没有这样做。事实上,这样做是由 Perl 捕获和处理的:

% perl -we 'eval { die undef }; print "EVAL_ERROR: $@"'
Use of uninitialized value in die at -e line 1.
EVAL_ERROR: Died at -e line 1.

© www.soinside.com 2019 - 2024. All rights reserved.