3

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

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

鉴于此代码,我得到一个致命错误。

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

在 ./test.pl 第 6 行使用“strict subs”时,不允许使用裸词“STDOUT”。由于编译错误,./test.pl 的执行中止。

为什么autodie指向严格的潜艇作为这个错误的根源——当在第一个例子中明确严格并且我没有错误时。

错误diagnostics解释如下..

在 ./test.pl 第 7 行使用“strict subs”时,不允许使用裸词“STDOUT”。由于编译错误,./test.pl 的执行中止 (#1) (F) 使用“strict subs”时,a bareword 只允许作为子例程标识符,在大括号中或“=>”符号的左侧。也许您需要预先声明一个子程序?

这都可以通过做来解决

open STDERR, '>&', *STDOUT;

那么它不是一个bareword,但是为什么bareword特别适用于open without autodie,而不是autodie?这里发生了其他事情吗?

4

1 回答 1

8

autodieopen通过导出一个Perl 使用的有利于操作符的 sub 来完成它的任务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")对于此类运算符返回 undefined,但prototype("CORE::open")会不准确地报告open' 的解析规则等同于*;$@原型。
于 2020-01-22T23:01:47.800 回答