为什么在没有粗逗号和严格的 use 行上允许前导连字符选项?
Why are leading-hyphen options permitted on `use` lines without fat comma and with strict?
为什么下面的 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"
, the 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
行产生了相同的解析。但是,两者都引用了原始示例没有的引用。我缺少什么使原始示例(strict
,没有 =>
)合法?谢谢!
来自perlop
符号一元运算符
如果操作数是数字,一元“-”执行算术否定,包括任何
看起来像数字的字符串。如果操作数是标识符,则为字符串
返回由与标识符连接的减号组成的。
否则,如果字符串以加号或减号开头,则字符串以
返回相反的符号。 这些规则的一个效果是 -bareword 是
相当于字符串 "-bareword". 但是,如果字符串以 a 开头
非字母字符(不包括“+”或“-”),Perl 将尝试转换
将字符串转换为数字并执行算术否定。如果字符串
无法干净地转换为数字,Perl 将发出警告 Argument
"the string" 不是负数 (-) at ....
因此,由于 Perl 解析规则,即使在 use strict
下,-name 也被视为“-name”
您已经引用了 perldoc perlop
,但它在这里是相关的。
Unary -
performs arithmetic negation if the operand is numeric, including any string that looks like a number. If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. ... One effect of these rules is that -bareword
is equivalent to the string "-bareword"
.
在应用 strict
检查 之前,一元减号运算符的这种行为应用于裸词 。因此,一元减号是一种引用运算符,也适用于严格模式。
同样,barewords作为方法调用中的invocant只要不是函数调用就不需要引用:
Foo->bar; # 'Foo'->bar(); --- but only if no sub Foo exists
print->bar; # print($_)->bar();
但是,一元减号行为似乎是由于常量折叠造成的,而不是由于解析器中的特殊情况造成的。例如,这段代码
use strict;
0 ? foo : bar;
只会抱怨裸字 "bar" 被禁止,这表明裸字检查在解析和编译过程中发生得很晚。在一元减号的情况下,此时裸字已经被常量折叠成适当的字符串值,并且没有裸字仍然可见。
虽然这可以说是错误的,但也不可能在不破坏向后兼容性的情况下进行更改——并且这种行为被许多模块使用,例如 use parent
来传达选项。还比较命令行界面上的类似习语,其中选项通常以破折号开头。
为什么下面的 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"
, the unary minus 将该字符串转换为"-bareword"
,并且生成的字符串将进入use
导入列表。例如:package MyHash; use Tie::Hash; use parent -norequire, "Tie::StdHash";
同理,如果有一个胖逗号,我也能理解。
-foo => bar
变为"-foo", bar
因为=>
turnsfoo
into"foo"
,然后一元减号再次发挥其魔力。例如:package MyHash; use strict; use Tie::Hash; use parent -norequire => "Tie::StdHash";
这两个示例都对 use
行产生了相同的解析。但是,两者都引用了原始示例没有的引用。我缺少什么使原始示例(strict
,没有 =>
)合法?谢谢!
来自perlop
符号一元运算符
如果操作数是数字,一元“-”执行算术否定,包括任何 看起来像数字的字符串。如果操作数是标识符,则为字符串 返回由与标识符连接的减号组成的。 否则,如果字符串以加号或减号开头,则字符串以 返回相反的符号。 这些规则的一个效果是 -bareword 是 相当于字符串 "-bareword". 但是,如果字符串以 a 开头 非字母字符(不包括“+”或“-”),Perl 将尝试转换 将字符串转换为数字并执行算术否定。如果字符串 无法干净地转换为数字,Perl 将发出警告 Argument "the string" 不是负数 (-) at ....
因此,由于 Perl 解析规则,即使在 use strict
您已经引用了 perldoc perlop
,但它在这里是相关的。
Unary
-
performs arithmetic negation if the operand is numeric, including any string that looks like a number. If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. ... One effect of these rules is that-bareword
is equivalent to the string"-bareword"
.
在应用 strict
检查 之前,一元减号运算符的这种行为应用于裸词 。因此,一元减号是一种引用运算符,也适用于严格模式。
同样,barewords作为方法调用中的invocant只要不是函数调用就不需要引用:
Foo->bar; # 'Foo'->bar(); --- but only if no sub Foo exists
print->bar; # print($_)->bar();
但是,一元减号行为似乎是由于常量折叠造成的,而不是由于解析器中的特殊情况造成的。例如,这段代码
use strict;
0 ? foo : bar;
只会抱怨裸字 "bar" 被禁止,这表明裸字检查在解析和编译过程中发生得很晚。在一元减号的情况下,此时裸字已经被常量折叠成适当的字符串值,并且没有裸字仍然可见。
虽然这可以说是错误的,但也不可能在不破坏向后兼容性的情况下进行更改——并且这种行为被许多模块使用,例如 use parent
来传达选项。还比较命令行界面上的类似习语,其中选项通常以破折号开头。