给定这样的代码,我没有得到任何警告。
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
运算符无法被子运算符准确复制。这解释了观察到的差异。
- 通常,对于这样的运算符,
prototype("CORE::opname")
返回未定义,但prototype("CORE::open")
错误地报告open
的解析规则等效于*;$@
原型。