Нечетное число элементов в анонимном хэше
Я пытаюсь понять этот код Perl...
Если есть один поток, он работает, если есть 2 или более потоков, он предупреждает с нечетным количеством элементов в анонимном хеше. Кажется, он возвращает массив в этом случае. Как добавить элементы массива в @streams? Кажется, что он правильно добавлен для случая HASH в предложении if. Является ли предложение else блоком?
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;
меня
Невозможно использовать string ( "-1" ) как HASH ref, в то время как "строгие ссылки" используются в строке 317 xyz-handler.pl.
некоторый вывод самосвала
$VAR1 = {
'streamIdList' => [
{
'name' => 'asdfasdfadsfasdfa'
},
{
'name' => 'cpp-62bad47d63cfb25e76b29a4801c61d8d'
}
],
'includeDefectInstances' => 'true',
'includeHistory' => 'true'
};
Ответы
Ответ 1
Список, назначенный хешу, представляет собой набор пар ключ/значение, поэтому количество элементов должно быть четным.
Поскольку оператор =>
представляет собой немного больше, чем запятую, а массив @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',
};
поэтому, надеюсь, вы увидите, что вы получите предупреждение, если у вас есть четное количество элементов в массиве.
Чтобы исправить вещи, вам нужно, чтобы значение хэш-элемента было ссылкой на массив, которое является скаляром и не будет нарушать схему вещей
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;
}
Ответ 2
Назначение в:
my $stream_defect_filter_spec = {
'streamIdList' => @streams, # <---- THIS ONE
'includeDefectInstances' => 'true',
'includeHistory' => 'true',
};
неверно, вы получаете хэш-ключи из элемента массива 1 3 5....
Вероятно, вам нужно назначить ссылку на массив, а не на массив:
'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"] }
Разница отчетливо видна.