为什么这个关于严格订阅的错误只在自动模式下触发?

Why does this error about strict subs only trigger under autodie?

提问人:Evan Carroll 提问时间:1/23/2020 更新时间:1/23/2020 访问量:375

问:

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

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

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

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

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

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

错误是这样解释的..diagnostics

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

这一切都可以通过执行来解决

open STDERR, '>&', *STDOUT;

那么它就不是裸词了,但是为什么裸字是专门针对没有自动模具打开的,而不是有自动模具的呢?这里还有什么事情发生吗?

Perl 警告 裸字

评论

3赞 Grinnz 1/23/2020
因为 autodie 用没有相同解析器的常规 Perl 函数替换了内置的 特殊情况。
5赞 brian d foy 1/23/2020
这是反对使用 .它有人们意想不到的边缘情况。在许多情况下,我认为这种权衡是不值得的,尤其是当我想向用户提供有用的错误消息而不是向程序员提供技术细节信息时。autodie

答:

8赞 ikegami 1/23/2020 #1

autodie通过导出 Perl 用于 operator 的 sub 来实现其任务。openopen

$ 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
...

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


  1. 通常,对于此类运算符返回 undefined,但会错误地报告解析规则等同于原型。prototype("CORE::opname")prototype("CORE::open")open*;$@

评论

0赞 Evan Carroll 2/14/2021
这是因为常规函数不能接受裸语吗?但是他们可以接受typeglobs吗?如果是这样,如果你想把它添加到你的第一句话中,我会把它标记为接受。否则我不确定我是否在关注,并想知道为什么是特别的(或者它是否特别。总是更合适,他们不同吗?openSTDOUTSTDOUT*STDOUT
0赞 ikegami 2/14/2021
在所讨论的用法中,接受一个裸词,因为前面的参数是 .如果是第二个论点,一个裸语就不会被接受(下)。原型无法复制这种条件行为。open>&>use strict