I'm trying to understand this Perl code...
If there is one stream it works, if there are 2 or more streams it warns with odd number of elements in anonymous hash. It seems to return an array in that case. How do I add the array elements correctly to @streams? It appears to add correctly for the HASH case in the if clause. Is the else clause 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);
I'm adding the next lines...
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).")";
}
It now errors with
Web API returned error code S:Server: calling getStreamDefects: No stream found for name null. $VAR1 = -1; me Can't use string ("-1") as a HASH ref while "strict refs" in use at xyz-handler.pl line 317.
some Dumper output
$VAR1 = {
'streamIdList' => [
{
'name' => 'asdfasdfadsfasdfa'
},
{
'name' => 'cpp-62bad47d63cfb25e76b29a4801c61d8d'
}
],
'includeDefectInstances' => 'true',
'includeHistory' => 'true'
};
An anonymous hash is simply a hash without a name. Both named and anonymous hashes have references, and \%hash is no more a direct reference than { foo => "bar" } . You imply that the latter is an indirect reference.
Perl | exists() Function The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.
The list assigned to a hash is a set of key/value pairs, which is why the number of elements must be even.
Because the =>
operator is little more than a comma, and the @streams
array is flattened in the list, this
my $stream_defect_filter_spec = {
'streamIdList' => @streams,
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
is equivalent to this
my $stream_defect_filter_spec = {
'streamIdList' => $streams[0],
$streams[1] => $streams[2],
$streams[3] => $streams[4],
...
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
so I hope you can see that you will get the warning if you have an even number of elements in the array.
To fix things you need the value of the hash element to be an array reference, which is a scalar and won't upset the scheme of things
my $stream_defect_filter_spec = {
'streamIdList' => \@streams,
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
that way you can access the array elements as
$stream_defect_filter_spec->{streamIdList}[0]
etc.
And by the way you can tidy up your code substantially by letting map
do what it's good at:
if (ref $x eq 'HASH') {
push @streams, $x->{id};
}
elsif (ref $x eq 'ARRAY') {
push @streams, map $_->{id}, @$x;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With