为什么以下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
无效,我会理解的。裸字norequire
将become 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
,没有=>
)合法?谢谢!
答案 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”