我在perl中有一个子例程来检查数组是否包含特定元素,如果它包含返回TRUE,则返回false ..由于搜索到的元素http_TestABC不在数组中但仍然返回TRUE,下面的代码应该重新返回false。无法计算为什么会这样。很多指点赞赏 感谢
#!/usr/bin/perl
use strict;
use warnings;
my @result_listosp; # defines an empty array
$result_listosp[0] = "origin-server-pool-1"; # array has one element
$result_listosp[1] = "http-pool-OSP2"; # array has 10 elements now
my $osp="http_TestABC";
my $status_osp_check= check_if_entity_exists(@result_listosp,$osp);
print $status_osp_check;
sub check_if_entity_exists()
{
my @entityarray = @_;
my $entity = $_[1];
my $status="FALSE";
if ( grep( /^$entity$/, @entityarray ) ) {
$status="TRUE";
return $status;
}
else {
return $status;
}
}
答案 0 :(得分:12)
它总是返回true,因为你误解了如何将参数传递给子例程。当你这样做时:
my @entityarray = @_;
my $entity = $_[1];
您将所有参数分配给@entityarray
,将第二个参数分配给$entity
。所以当然如果你检查$entity
的所有元素,它将是其中之一。
您也不应该使用原型,即子名后面的括号。除非你知道他们做了什么,否则最好忽略它们,因为它们具有非常特殊的功能。
解决方案,反驳论点:
check_if_entity_exists($foo, @bar);
...
sub check_if_entity_exists {
my $entity = shift; # the first arg
my @entityarray = @_; # the rest
这是因为perl在作为参数传递时会使数组变平,因此它只是参数列表中的元素,而不是单个变量。 Perl无法知道你是否通过了数组。 除非你玩原型。除了作为练习外,我不推荐。如果您执行以下操作:
sub foo (\@$) {
然后你可以将数组作为参数传递,就像push
和shift
一样。
您也可以将数组作为参考传递,在这种情况下,您可以执行以下操作:
foo(\@array, $var);
sub foo {
my $aref = shift; # @$aref is now @array
my $var = shift;
在这种情况下,您需要注意使用传递给子例程的相同数组,而不是副本。因此,如果您更改它,更改是永久性的。
注意:正如PSIAlt指出的那样,如果您的意图是字面匹配,则不应在正则表达式中直接使用任意字符串。其中可能存在导致副作用的元字符。做其中之一:
grep /^\Q$entity/, .. # quote meta characters
grep { $_ eq $entity } ... # check string equality
正如PSIAlt所暗示的那样,eq
是最直接的解决方案,除非你需要正则表达式,否则应该是你使用的那个。