请你能解释一下这个显然不一致的行为:
use strict;
my @a;
print "a" x 2; # this prints: aa
@a = "a" x 2; print @a; # this prints: aa
print ("a") x 2; # this prints: a
@a = ("a") x 2; print @a; # this prints: aa
最后一个不应该打印一个'a'吗?
编辑:好的,现在这对我来说更有意义: “二进制”x“是重复运算符...在列表上下文中,如果左操作数括在括号中或者是由qw / STRING /形成的列表,则它会重复列表。” perlop
这对我来说很清楚(二进制x - 为什么使用二进制这个词?是否有一个否定的X?) 但无论如何: @a =(“a”)x 2#似乎在列表上下文中,因为我们在开头有一个数组 - 数组不是列表,但是它包含一个列表,所以我想我们可能有一个列表上下文,(不是数组上下文,尽管它们可能是同义词)。
我认为“左操作数”是(“a”)。 (或者是那个或@a)。 perlop没有说明操作数实际上是什么,查询perldoc.perl.org给出“找不到匹配”,谷歌搜索给出“在计算机编程中,操作数是用于描述任何能够被操纵的对象的术语”。就像数组一样。
所以左操作数可能会括在括号中,所以它可能会“重复列表”。该列表是:("a") x 2
或者是:("a")
如果我们重复("a") x 2
,我们会得到("a") x 2 ("a") x 2
。这似乎不对。
如果我们输入:print $a[1]
,我们会得到一个'a',所以“它重复列表”意味着Perl将("a") x 2
变为("a", "a")
,因此我们有效地获得了{{1} }
但是,@a=("a", "a")
不会变成print ("a") x 2
。那是因为print是一个具有高优先级的“列表运算符”。所以我们有效地得到:("a", "a")
数组是一个术语,因此它也具有高优先级,但@ a = stuff涉及赋值运算符=,它具有相对较低的优先级。所以它与印刷品完全不同。
答案 0 :(得分:7)
在您的脚本中添加use warnings;
,然后您将获得警告,如
print (...) interpreted as function .
Useless use of repeat (x) in void context .
像print (("a") x 2);
#这样打印:aa
正如您在评论中提到的,如何设置代码格式,我想说看 Perltidy 。
Perltidy 是一个Perl脚本,用于缩进和重新格式化Perl脚本以使其更易于阅读。如果你编写Perl脚本,或者花很多时间阅读它们,你可能会发现它很有用。
有关 Perltidy 的更多信息:
您可以下载perltidy并运行它 使用其默认值,或自定义它以使用您喜欢的支撑样式,缩进宽度等。
自定义很简单,并且有很多选项。默认值通常是一个很好的起点。
Perltidy还可用于生成代码的彩色HTML输出。
Perltidy带有一套合理的默认值;但它们可能不适合你。幸运的是,您可以使用 tidyview 作为图形用户界面来预览perltidy对代码的更改,并查看哪些选项最适合您。您可以从CPAN下载tidyview。
注意:始终在脚本开头添加use strict
和use warnings
。
答案 1 :(得分:4)
我认为你得到奇怪行为的原因是因为perl的print
命令是期望列表。引自relevant documentation:
另外注意不要使用左括号跟随print关键字,除非你想要相应的右括号来终止print的参数;将括号括在所有参数周围。
放括号使它就像一个函数。考虑一下您是否执行此测试用例:
x("y") x 2;
sub x {
my $y = shift;
print "1: $y\n"; #result 1: y
my $y = shift;
print "2: $y\n"; #result 2:
}
当作为函数调用编写时,对于正在计算其参数的函数,结果是一致的,而不是在执行以下操作后正在计算的赋值。
答案 2 :(得分:3)
你被一个常见的Perl解析陷阱所困扰。您的第三个语句print ("a") x 2
被解析为:
(print ("a")) x 2;
您可以添加另一组括号来修复解析:
print (("a") x 2); # prints aa