在"打印"开头的点声明?

时间:2016-05-31 18:10:09

标签: perl operations

我在使用Perl脚本时遇到了一些奇怪的事情。它是关于使用一个点给出不同的结果。

perlop没有任何改变,或者我只是吹过它。我在看Operator Precedence and Associativity

print "I'd expect to see 11x twice, but I only see it once.\n";
print (1 . 1) . "3";
print "\n";
print "" . (1 . 1) . "3\n";
print "Pluses: I expect to see 14 in both cases, and not 113, because plus works on numbers.\n";
print (1 . 1) + "3";
print "\n";
print "" + (1 . 1) + "3\n";

在一开始就引用引号是一个可以接受的解决方法,可以得到我想要的东西,但是这里发生的事情是我错过的操作顺序?有什么规则可以学习?

2 个答案:

答案 0 :(得分:14)

当您将第一个参数放在括号中的print时,Perl将其视为函数调用语法。

所以这个:

print (1 . 1) . "3";

被解析为:

print(1 . 1)  . "3";

或等同于:

(print 1 . 1) . "3";

因此,Perl打印“11”,然后获取该print调用的返回值(如果成功则为1),将3连接到它,并且 - 因为整个表达式在void上下文中 - 与结果13完全没有关系。

如果您在启用警告的情况下运行代码(通过命令行上的-wuse warnings;编译指示),您将收到这些警告,以识别您的错误:

$ perl -w foo.pl
print (...) interpreted as function at foo.pl line 2.
print (...) interpreted as function at foo.pl line 6.
Useless use of concatenation (.) or string in void context at foo.pl line 2.
Useless use of addition (+) in void context at foo.pl line 6.

正如Borodin在下面的评论中指出的那样,您不应该依赖-w(或代码内的等效$^W);生产代码应始终使用warnings编译指示,最好使用use warnings qw(all);。虽然在此特定情况下无关紧要,但您也应该use strict;,尽管通过use 版本 ;为Perl版本的5.11请求现代功能或更高版本也会自动打开strict

答案 1 :(得分:4)

如果命名运算符(或子调用)后面跟着parens,那些parens会分隔操作数(或参数)。

print (1 . 1) . "3";       ≡  ( print(1 . 1) ) . "3";
print "" . (1 . 1) . "3";  ≡  print("" . (1 . 1) . "3");

请注意,如果您使用(use strict;和)use warnings qw( all );,Perl会提醒您注意您的问题。

print (...) interpreted as function at a.pl line 2.
print (...) interpreted as function at a.pl line 6.
Useless use of concatenation (.) or string in void context at a.pl line 2.
Useless use of addition (+) in void context at a.pl line 6.
I'd expect to see 11x twice, but I only see it once.
11
113
Pluses: I expect to see 14 in both cases, and not 113, because plus works on numbers.
11
Argument "" isn't numeric in addition (+) at a.pl line 8.
14