3

为什么以下use行是合法的 Perl 语法?(改编自 POD for parent;在 Cygwin 上的 Perl 5.26.2 x64 上测试。)

package MyHash;
use strict;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
       #   ^^^^^^^^^^ A bareword with nothing to protect it!

在 下-MO=Deparseuse线变为

use parent ('-norequire', 'Tie::StdHash');

但我无法从use文档 中看出引用的-norequire来源。

  • 如果use strict没有生效,我会理解的。裸词norequire变成字符串 "norequire"一元减号会变成字符串"-bareword",而结果字符串会进入use导入列表。例如:

    package MyHash;
    use Tie::Hash;
    use parent -norequire, "Tie::StdHash";
    
  • 同样,如果有一个粗逗号,我会理解的。 -foo => bar变为"-foo", bar因为=> 变为foo"foo"然后一元减号再次发挥其魔力。例如:

    package MyHash;
    use strict;
    use Tie::Hash;
    use parent -norequire => "Tie::StdHash";
    

这两个示例都为该use行产生了相同的 deparse。但是,两者都引用了原始示例没有引用。我遗漏了什么使原始示例(带strict,不带=>)合法?谢谢!

4

2 回答 2

4

你已经引用了perldoc perlop,但它在这里是相关的。

-如果操作数是数字,包括任何看起来像数字的字符串,一元将执行算术否定。如果操作数是标识符,则返回由与标识符连接的减号组成的字符串。...这些规则的一个效果-bareword是相当于字符串"-bareword"

一元减号运算符的这种行为在应用检查之前strict应用于裸字。因此,一元减号是一种引用运算符,也适用于严格模式。

类似地,只要不是函数调用,作为方法调用中的调用者的裸词就不需要引用:

Foo->bar;    # 'Foo'->bar(); --- but only if no sub Foo exists
print->bar;  # print($_)->bar();

但是,一元减号行为似乎是由于不断折叠,而不是由于解析器中的特殊情况。例如,这段代码

use strict;
0 ? foo : bar;

只会抱怨不允许使用裸词“bar”,这表明在解析和编译期间,裸词检查发生得很晚。在一元减号的情况下,裸字此时已经被常量折叠成适当的字符串值,并且没有裸字保持可见。

虽然这可以说是有问题的,但在不破坏向后兼容性的情况下也无法进行更改——这种行为被许多模块使用,例如use parent通信选项。还要比较命令行界面上的类似习惯用法,其中选项通常以破折号开头。

于 2018-12-10T14:40:49.227 回答
1

perlop

符号一元运算符

如果操作数是数字,则一元“-”执行算术否定,包括任何看起来像数字的字符串。如果操作数是标识符,则返回由与标识符连接的减号组成的字符串。否则,如果字符串以加号或减号开头,则返回以相反符号开头的字符串。这些规则的一个效果是 -bareword 等价于字符串“-bareword”。但是,如果字符串以非字母字符(不包括“+”或“-”)开头,Perl 将尝试将字符串转换为数字并执行算术否定。如果字符串不能干净地转换为数字,Perl 将给出警告 Argument "the string" is not numeric in negation (-) at ...。

所以由于 Perl 解析的规则 -name 即使在下面也被视为“-name”use strict

于 2018-12-10T14:40:29.217 回答