为什么这个关于严格潜艇的错误只在自动下触发?



给定这样的代码,我没有得到任何警告。

use strict;
use warnings;
open STDERR, '>&', STDOUT;

给定此代码,我收到一个致命错误。

use strict;
use warnings;
use autodie;
open STDERR, '>&', STDOUT;
在.

/test.pl 使用"严格子"时不允许使用裸词"STDOUT" 第 6 行。由于编译错误,./test.pl 的执行中止。

为什么autodie指出严格的子是这个错误的根源——当在第一个例子中明显严格时,我没有错误。

有了diagnostics错误是这样解释的。.

./test.pl 第7行使用"严格子"时不允许使用"STDOUT"的裸词。 由于编译错误,./test.pl 的执行中止 (F( 使用"严格子"时,只允许将空字作为子例程标识符,在大括号中或"=>"符号的左侧。 也许您需要预先声明一个子例程?

这一切都可以通过做来解决

open STDERR, '>&', *STDOUT;

那么它不是一个裸词,但是为什么裸词是没有自动的打开,而不是自动的?这里是否发生了其他事情?

>autodie通过导出一个名为open的子来实现其任务,Perl 使用该子子来支持open运算符。

$ perl -MO=Concise,-exec -e'             open(my $fh, "<", "foo")'
...
8  <@> open[t3] vK/3
...
$ perl -MO=Concise,-exec -e'use autodie; open(my $fh, "<", "foo")'
...
7  <#> gv[*open] s
8  <1> entersub vKS
...

open运算符具有无法被原型复制的特殊解析规则[1],因此open运算符无法被子运算符准确复制。这解释了观察到的差异。


  1. 通常,对于这样的运算符,prototype("CORE::opname")返回未定义,但prototype("CORE::open")错误地报告open的解析规则等效于*;$@原型。

最新更新