我正在尝试理解这个Perl代码...
如果有一个流可以工作,如果有2个或更多个流,它会以匿名哈希中的奇数个元素发出警告。在这种情况下似乎返回一个数组。如何正确地将数组元素添加到@streams?它似乎为if子句中的HASH情况正确添加。 else子句是否是bunk?
my $x = $viewedProjectDataObj->{streams};
if (ref($x) eq 'HASH') {
push(@streams, $x->{id});
} elsif (ref($x) eq 'ARRAY') {
print "$x\n";
print "@$x\n";
my @array = @$x;
foreach my $obj (@array) {
print "in $obj\n";
print Dumper( $obj);
push(@streams, ($obj->{id}) );
}
}
print "streamcount " . @streams % 2;
print Dumper(@streams);
my $stream_defect_filter_spec = {
'streamIdList' => @streams,
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
my @streamDefects = $WS->get_stream_defects($defectProxy, \@cids, $stream_defect_filter_spec);
print Dumper(@streamDefects);
我正在添加下一行...
if ($defectSummary->{owner} eq "Various") {
foreach (@streamDefects) {
if (exists($_->{owner})) {
$defectSummary->{owner} = $_->{owner};
last;
}
}
}
my $diref = $streamDefects[0]->{defectInstances};
if ($diref) {
my $defectInstance;
if (ref($diref) eq 'HASH') {
$defectInstance = $diref;
} elsif (ref($diref) eq 'ARRAY') {
$defectInstance = @{$diref}[0];
} else {
die "Unable to handle $diref (".ref($diref).")";
}
现在错误
Web API返回错误代码S:服务器:调用getStreamDefects:找不到流 名称为null。 $ VAR1 = -1; 我 在xyz-handler.pl第317行使用“strict refs”时,不能使用字符串(“ - 1”)作为HASH引用。
一些Dumper输出
$VAR1 = {
'streamIdList' => [
{
'name' => 'asdfasdfadsfasdfa'
},
{
'name' => 'cpp-62bad47d63cfb25e76b29a4801c61d8d'
}
],
'includeDefectInstances' => 'true',
'includeHistory' => 'true'
};
答案 0 :(得分:16)
分配给散列的列表是一组键/值对,这就是元素数量必须是偶数的原因。
因为=>
运算符只是一个逗号,并且@streams
数组在列表中展平,所以
my $stream_defect_filter_spec = {
'streamIdList' => @streams,
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
等同于此
my $stream_defect_filter_spec = {
'streamIdList' => $streams[0],
$streams[1] => $streams[2],
$streams[3] => $streams[4],
...
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
所以我希望你能看到,如果数组中有甚至个元素,你就会收到警告。
要解决问题,你需要将hash元素的值作为数组 reference ,这是一个标量,不会扰乱事物的方案
my $stream_defect_filter_spec = {
'streamIdList' => \@streams,
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
这样你可以像
那样访问数组元素$stream_defect_filter_spec->{streamIdList}[0]
等
顺便说一句,通过让map
做出擅长的事情,你可以大大整理你的代码:
if (ref $x eq 'HASH') {
push @streams, $x->{id};
}
elsif (ref $x eq 'ARRAY') {
push @streams, map $_->{id}, @$x;
}
答案 1 :(得分:8)
分配在:</ p>
my $stream_defect_filter_spec = {
'streamIdList' => @streams, # <---- THIS ONE
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
不正确,您从1 3 5th ...数组元素中获取哈希键。
您可能想要分配对数组的引用,而不是数组本身:
'streamIdList' => \@streams,
不需要的示例(如代码中所示):
use strict;
use warnings;
use Data::Dump;
my @z = qw(a b c x y z);
dd \@z;
my $q = {
'aa' => @z,
};
dd $q;
不需要的结果:
["a", "b", "c", "x", "y", "z"]
Odd number of elements in anonymous hash at a line 12.
{ aa => "a", b => "c", x => "y", z => undef }
^-here
分配参考的示例
use strict;
use warnings;
use Data::Dump;
my @z = qw(a b c x y z);
dd \@z;
my $q = {
'aa' => \@z,
};
dd $q;
产生
["a", "b", "c", "x", "y", "z"]
{ aa => ["a", "b", "c", "x", "y", "z"] }
差异清晰可见。