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

cxw*_*cxw 5 syntax perl punctuation bareword language-lawyer

为什么下面的use行是合法的 Perl 语法?(改编自父级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!
Run Code Online (Sandbox Code Playgroud)

在 下-MO=Deparse,该use行变为

use parent ('-norequire', 'Tie::StdHash');
Run Code Online (Sandbox Code Playgroud)

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

  • 如果use strict不是强制的话,我会理解的。裸字norequire变成 string "norequire"一元减号将将该字符串变成"-bareword",并且生成的字符串将进入use导入列表。例如:

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

    package MyHash;
    use strict;
    use Tie::Hash;
    use parent -norequire => "Tie::StdHash";
    
    Run Code Online (Sandbox Code Playgroud)

这两个示例都会对use线条产生相同的稀疏效果。然而,两者都引用了原始示例中没有的内容。我缺少什么使原始示例(带strict,不带=>)合法?谢谢!

amo*_*mon 5

您已经引用过perldoc perlop,但它与此处相关。

\n\n
\n

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

\n
\n\n

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

\n\n

同样,方法调用中作为调用者的裸字只要不是函数调用就不需要加引号:

\n\n
Foo->bar;    # \'Foo\'->bar(); --- but only if no sub Foo exists\nprint->bar;  # print($_)->bar();\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
use strict;\n0 ? foo : bar;\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n

  • 另请注意,“-Foo'Bar”变为“-Foo::Bar” - 但与“-Foo::Bar”不同,除非包 Foo 存在,否则会给出裸字错误。这(与隐式引用的基本有据可查的概念不同)可以说是有问题的 (4认同)
  • 作为方法调用目标的 barewords 应该被引用。`Foo->bar` 不是* `'Foo'->bar` 如果存在子 Foo,它是 `Foo()->bar`。您应该使用 `Foo::->bar` 或 `'Foo'->bar`。 (3认同)