我正在编写Mastering Perl的“错误处理和报告”一章。在perlvar的条目中,它说:$@
来自最后一个 eval() 运算符的 Perl 语法错误消息。如果 $@ 是空字符串,则最后一个 eval() 解析并正确执行(尽管您调用的操作可能以正常方式失败)。
现在我想知道eval何时可能无法正确执行,留下$@
一个未定义的值。有没有这样的案例?
这是一种方法(但在阅读之前请坐下。;))
$@ = 123;
eval q{
$@ = 456;
print ">>>$@<<<\n";
goto SKIP;
};
SKIP:
print ">>>$@<<<\n";
Try::Tiny 文档的背景部分包含一些关于如何$@
破坏以及为什么 Try::Tiny 会特别注意避免破坏的信息,并且总是测试返回值eval
而不是测试$@
真实性。他们都在那里,因为有人在某个时候遇到了他们,但我认为场景中的eval
场景DESTROY
是最有可能绊倒某人的场景。基本上,如果die
导致某个对象超出范围,并且该对象有一个DESTROY
调用eval
,那么您die
开始使用的值将不可挽回地丢失。假设eval
inDESTROY
不抛出错误,$@
将""
跟随 external eval
。
谁说设置$@
为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.
';