Perl的$@在eval之后会是undefined吗?

pbwdgjma  于 8个月前  发布在  Perl
关注(0)|答案(4)|浏览(55)

我正在编写Mastering Perl"Error Handling and Reporting"章节。在perlvar$@条目中,它说:
来自最后一个eval()操作符的Perl语法错误消息。如果$@是空字符串,则最后一个eval()正确解析和执行(尽管您调用的操作可能以正常方式失败)。
现在我想知道什么时候eval可能无法正确执行,留下一个未定义的值$@。有没有这样的情况?

irtuqstp

irtuqstp1#

Try::Tiny文档的背景部分包含了一些关于如何击败$@以及为什么Try::的信息。Tiny特别注意避免混乱,总是测试eval的返回值,而不是测试$@的真实性。所有这些都在那里,因为 * 有人 * 在某个时候遇到了它们,但我认为eval-in-DESTROY场景是最有可能绊倒别人的场景。基本上,如果die导致某个对象超出范围,并且该对象有一个DESTROY调用eval,那么您die d开始使用的值将无法挽回地丢失。假设DESTROY * 中的eval * 不会抛出错误,$@将是"",后面是外部eval

tsm1rwdh

tsm1rwdh2#

这里有一个方法来做到这一点(但在你阅读之前坐下来。

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

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

cuxqih213#

如果有人读到这个问题,仍然想知道(像我一样)$@是否可以在eval之后未定义,我相信答案是否定的(我也读到过old 5.8.3 docs for $@中的“null”,我感到困惑,因为“null”不是Perl中经常使用的术语。
我不知道Perl的内部机制来证实这一点,但看起来这些文档最终在2015年用this commit修复了,这是由于this issue。perlvar的条目现在说“空字符串”而不是“null”:
来自最后一个“eval”操作符的Perl错误,即捕获的最后一个异常。对于“eval BLOCK”,这是一个运行时错误消息或字符串或引用“die”被调用。“eval STRING”形式也捕获语法错误和其他编译时异常。
如果没有错误发生,“eval”将$@设置为空字符串。
另外,由于$@可以设置为“string or reference die was called with”,我想我会确保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.
p8h8hvxi

p8h8hvxi4#

谁说要把$@设为undef了?
“The last eval()parsed and executed correctly”没有任何意义:eval在运行时不会被解析。当然,它的意思是“the last eval()which expression was parsed and executed correctly”。换句话说,“the last eval()which expression compiled and didn't throw any exceptions when executed”。

>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.
';

相关问题