这个节目
use warnings;
use strict;
use feature qw(say);
{
#use autodie; # all good when this is uncommented
no autodie;
}
open my $OLDSTD, '>&', *STDOUT; #--> line 10 (program fails)
open *STDOUT, '>', 'stdout.out';
say "$$ done";
中止
在 problem_no_autodie.pl 第 10 行调用了未定义的子例程。
重申代码中的注释:如果首先有一个use autodie;
语句,那么一切都很好。(一切都很好,只有use autodie;
也很好。)奇怪的是,在与no autodie
声明相同的范围内,我也没有看到这样的问题。只有超出其范围的代码才会失败!有点反作用域,嗯?
如果这个作用域no autodie
是在使用之后出现的,*STDOUT
那么一切都很好。*STDOUT
在(范围内)之后进一步使用,no autodie
会使程序失败。
文档中提到了一个涉及裸词(我不完全理解)的问题,并且该程序确实失败了STDOUT
- 但我将它作为*STDOUT
.
所以它似乎*STDOUT
被视为用户的子,但我不明白这一点,也不明白范围是如何autodie
被击败的。(在某些版本中提到范围泄漏是一个错误,但以一种看似无关的方式。)这存在一个实际问题。
我不在autodie
我的代码中使用。但是考虑一下我确实使用的这个子
sub isatty {
no autodie;
state $isatty = open(my $tty, '+<', '/dev/tty');
return $isatty;
}
失败是合法的open
,因此我们必须autodie
在该范围内禁用,以防子用户打开它。那么所描述的行为会受到伤害吗?在什么情况下?
我对这种效果no autodie
和它超出其范围的泄漏以及它们所有奇怪的细节感到困惑。但真正令人担忧的是,我不确定如何保护使用上述库的代码免受这种行为的影响,因为我不理解它。有任何想法吗?
我在 CentOS 7.8 上的 5.16.3(系统)、5.26.2 和 5.30.0(perlbrew)下看到了这个
我在 5.32.0 上看不到这种行为;那里没有失败。
与的... or die $!
检查open
没有任何区别,因此为简单起见未显示。