Perl 为什么在“use”行中允许使用前导连字符选项,而不允许使用粗逗号和strict?
为什么下面的Perl 为什么在“use”行中允许使用前导连字符选项,而不允许使用粗逗号和strict?,perl,syntax,language-lawyer,punctuation,bareword,Perl,Syntax,Language Lawyer,Punctuation,Bareword,为什么下面的使用行合法的Perl语法?(改编自POD for;在Cygwin上的Perl 5.26.2 x64上测试。) 在-MO=Deparse下,use行变为 use parent ('-norequire', 'Tie::StdHash'); 但我无法从-norequire上的引用来判断 如果use strict不生效,我会理解的。barewordnorequire将“norequire”,将该字符串转换为“-bareword”,生成的字符串将进入使用导入列表。例如: package
使用行合法的Perl语法?(改编自POD for;在Cygwin上的Perl 5.26.2 x64上测试。)
在-MO=Deparse
下,use
行变为
use parent ('-norequire', 'Tie::StdHash');
但我无法从-norequire
上的引用来判断
- 如果
use strict
不生效,我会理解的。barewordnorequire
将“norequire”
,将该字符串转换为“-bareword”
,生成的字符串将进入使用
导入列表。例如:
package MyHash;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
package MyHash;
use strict;
use Tie::Hash;
use parent -norequire => "Tie::StdHash";
- 同样,如果有一个大逗号,我也能理解
-foo=>bar
变为“-foo”,bar
是因为=>
,然后一元负号再次发挥其魔力。例如:
package MyHash;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
package MyHash;
use strict;
use Tie::Hash;
use parent -norequire => "Tie::StdHash";
这两个示例都为use
行生成相同的deparse。然而,两人都引用了原始示例中没有的内容。我遗漏了什么使原始示例(带有严格的,没有=>
)合法?谢谢 来自perlop
符号一元运算符
如果操作数是数字(包括任何数字),则一元“-”执行算术求反
看起来像数字的字符串。如果操作数是标识符,则为字符串
返回由与标识符连接的减号组成的。
否则,如果字符串以加号或减号开头,则以
返回相反的符号。这些规则的一个效果是-空话是
相当于字符串“-bareword”。但是,如果字符串以
非字母字符(不包括“+”或“-”)Perl将尝试转换
将字符串转换为数字,并执行算术求反。如果字符串
无法干净地转换为数字,Perl将给出警告参数
“字符串”在…处的否定(-)中不是数字
因此,由于Perl解析的规则,即使在您已经引用的使用strict
下,-name也被视为“-name”,但它在这里是相关的
一元-
如果操作数是数字,包括任何看起来像数字的字符串,则执行算术求反。如果操作数是标识符,则返回由与标识符连接的减号组成的字符串。。。这些规则的一个效果是-bareword
相当于字符串“-bareword”
一元减号运算符的这种行为在应用严格检查之前应用于裸字。因此,一元负号是一种引用运算符,它也在严格模式下工作
类似地,方法调用中作为invocant的barewords不需要被引用,只要它们不是函数调用:
Foo->bar; # 'Foo'->bar(); --- but only if no sub Foo exists
print->bar; # print($_)->bar();
然而,一元负行为似乎是由于常数折叠,而不是由于解析器中的特殊情况。例如,此代码
use strict;
0 ? foo : bar;
只会抱怨不允许使用裸字“bar”,这表明裸字检查在解析和编译过程中发生得很晚。在一元减号的情况下,在该点上,裸字将已经被常数折叠成适当的字符串值,并且没有裸字保持可见
虽然可以说这是一个错误,但在不破坏向后兼容性的情况下进行更改也是不可能的——许多模块都使用这种行为,例如use parent
来通信选项。还可以比较命令行界面上的类似习惯用法,其中选项通常以破折号开头。应该引用作为方法调用目标的barewordsFoo->bar
不是'Foo'->bar
如果存在子Foo,则它是Foo()->bar
。您应该使用Foo::->bar
或'Foo'->bar
。还要注意-Foo'bar
变成“-Foo::bar”-但与-Foo::bar
不同,除非存在包Foo,否则会给出一个空字错误。这(与文献记载良好的-隐式引用的基本概念不同)可以说是有缺陷的