为什么我需要使用eval前本地化$ @?(Why do I need to localize $@

2019-09-19 02:44发布

我知道的一个事实,即$@是一个全局变量,我仍然无法弄清楚,为什么我在使用前需要进行本地化它EVAL :

例如:

eval { SOME_FUNC_THAT_MAY_DIE(); };
if ($@) {
  print "An error occured!\n";
}

唯一可能的事情,我能想到的是,如果一些信号处理程序将调用die在同一时间,我试着去阅读$@ ,我缺少什么吗?

Answer 1:

之所以说local $@之前调用eval是为了避免踩到你的来电者的$@ 。 这是不礼貌的子程序来改变任何全局变量(除非这是子程序的规定目的之一)。 这是不是真的有顶级代码(没有任何子程序中)的问题。

此外,在旧的Perl的,任何eval对象销毁过程中调用会揍全球$@ (如果对象被销毁,因为异常正在从抛出eval块),除非$@首次本地化。 这被固定在5.14.0 ,但很多人仍然在运行旧皮尔斯。



Answer 2:

的尝试::微型模块文档给出的理由(以及提供一种替代):

当你运行一个eval块并且取得了成功,$ @将被清除,可能重挫当前正在捕获的错误。 这使得超距作用,清除以前的错误,您的呼叫者可能尚未处理。 $ @必须为了避免这一问题,调用之前的eval正确定位。 更具体地讲,$ @是在EVAL,这也使得你死了(例如,错误堆栈进行异常对象时)之前不可能捕捉到以前的错误的开始重挫。


文章来源: Why do I need to localize $@ before using eval?