我必须为我的工作编辑一些Perl脚本。我从来没有写过一行Perl但是我可以让我的东西工作,直到我碰到一个奇怪的问题。考虑以下功能
sub trim {
my $s = shift;
$s =~ s/^\s+|\s+$//g;
return $s
}
用以下两种方式调用它:
my $previousVersionHash = readline( *CONFIG );
$previousVersionHash = trim($previousVersionHash);
$maxClients = readline( *CONFIG );
和
my $previousVersionHash = trim(readline( *CONFIG ));
$maxClients = readline( *CONFIG );
在第一种情况下,它运行正常,但是第二个代码段我收到警告,$maxClients
为空,而不是包含CONFIG
文件的第二行。
为什么这种奇怪的行为?请注意,当我使用sub trim($)
时也会发生这种情况。顺便说一下,我不知道这两个声明之间的区别,但这是记录在案的,所以我可以看一下这个问题是否重要。
答案 0 :(得分:4)
如果要返回列表或标量,Perl将允许它现在调用的函数。您可以使用wantarray进行检查。当您在列表上下文中调用它时,readline
会将所有行读入数组,就像您在第二个示例中所做的那样。
第二种方式是这样调用它,因为(就像@ ThisSuitIsBlackNot的评论所说)用户定义的子程序的参数总是在列表上下文中进行评估(假设没有原型):
my @array = readline( *CONFIG );
trim(@array);
所以这里*CONFIG
的所有其余行都放入数组@array
。您的trim
函数会丢弃除第一个以外的所有其他值。
要解决此问题并强制调整trim以进入标量上下文,请执行以下操作:
my $previousVersionHash = trim(scalar(readline( *CONFIG )));
或继续像你一样打电话。
要更新trim
以支持数组,您可以尝试以下内容:
sub trim {
my @a;
foreach my $s (@_) {
$s =~ s/^\s+|\s+$//g;
push @a, $s;
}
return @a;
}