为什么在“使用”行上允许使用前导连字符选项而又不使用粗逗号,并且使用严格的连字符?

时间:2018-12-10 14:09:01

标签: perl syntax language-lawyer punctuation bareword

为什么以下use行合法的Perl语法? (从parent的POD改编而来;在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=Deparse下,use行变为

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

但是我无法从use docs得知-norequire上的引号是来自哪里。

  • 如果use strict无效,我会理解的。裸字norequirebecome the string "norequire"unary minus会将字符串变成"-bareword",结果字符串将进入use导入清单。例如:

    package MyHash;
    use Tie::Hash;
    use parent -norequire, "Tie::StdHash";
    
  • 同样,如果有一个胖逗号,我会理解的。 -foo => bar之所以成为"-foo", bar,是因为=> turns foo into "foo",然后一元负号再次发挥其魔力。例如:

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

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

2 个答案:

答案 0 :(得分: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之类的许多模块用来传达选项。比较命令行界面上类似的习惯用法,其中选项通常以短划线开头。

答案 1 :(得分:1)

来自perlop

符号一元运算符

如果操作数为数字(包括任何数字),则一元“-”执行算术求反 看起来像数字的字符串。如果操作数是标识符,则为字符串 返回由与标识符连接的减号组成的。 否则,如果字符串以加号或减号开头,则字符串以 相反的符号被返回。 这些规则的一个作用是-bareword是 等效于字符串“ -bareword”。但是,如果字符串以a开头 非字母字符(不包括“ +”或“-”),Perl将尝试转换 将字符串转换为数字,然后进行算术求反。如果字符串 无法干净地转换为数字,Perl将给出警告参数 .... p处的“字符串”不是负号(-)。

因此,由于Perl解析的规则,即使在use strict下,-name仍被视为“ -name”