我知道的一个事实,即$@
是一个全局变量,我仍然无法弄清楚,为什么我在使用前需要进行本地化它EVAL :
例如:
eval { SOME_FUNC_THAT_MAY_DIE(); };
if ($@) {
print "An error occured!\n";
}
唯一可能的事情,我能想到的是,如果一些信号处理程序将调用die
在同一时间,我试着去阅读$@
,我缺少什么吗?
我知道的一个事实,即$@
是一个全局变量,我仍然无法弄清楚,为什么我在使用前需要进行本地化它EVAL :
例如:
eval { SOME_FUNC_THAT_MAY_DIE(); };
if ($@) {
print "An error occured!\n";
}
唯一可能的事情,我能想到的是,如果一些信号处理程序将调用die
在同一时间,我试着去阅读$@
,我缺少什么吗?
之所以说local $@
之前调用eval
是为了避免踩到你的来电者的$@
。 这是不礼貌的子程序来改变任何全局变量(除非这是子程序的规定目的之一)。 这是不是真的有顶级代码(没有任何子程序中)的问题。
此外,在旧的Perl的,任何eval
对象销毁过程中调用会揍全球$@
(如果对象被销毁,因为异常正在从抛出eval
块),除非$@
首次本地化。 这被固定在5.14.0 ,但很多人仍然在运行旧皮尔斯。
的尝试::微型模块文档给出的理由(以及提供一种替代):
当你运行一个eval块并且取得了成功,$ @将被清除,可能重挫当前正在捕获的错误。 这使得超距作用,清除以前的错误,您的呼叫者可能尚未处理。 $ @必须为了避免这一问题,调用之前的eval正确定位。 更具体地讲,$ @是在EVAL,这也使得你死了(例如,错误堆栈进行异常对象时)之前不可能捕捉到以前的错误的开始重挫。