匿名哈希中奇数个元素

DB-*_*DB- 12 perl

我试图理解这个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);
Run Code Online (Sandbox Code Playgroud)

我正在添加下一行......

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).")";
    }
Run Code Online (Sandbox Code Playgroud)

它现在出错了

Web API返回错误代码S:服务器:调用getStreamDefects:找不到名称为null的流.$ VAR1 = -1; 我不能使用字符串(" - 1")作为HASH引用,而在xyz-handler.pl第317行使用"strict refs".

一些Dumper输出

$VAR1 = {
      'streamIdList' => [
                          {
                            'name' => 'asdfasdfadsfasdfa'
                          },
                          {
                            'name' => 'cpp-62bad47d63cfb25e76b29a4801c61d8d'

                          }
                        ],
      'includeDefectInstances' => 'true',
      'includeHistory' => 'true'
    };
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 17

分配给散列的列表是一组键/值对,这就是元素数必须是偶数的原因.

因为=>运算符只是一个逗号,并且@streams数组在列表中被展平,这个

my $stream_defect_filter_spec = {
  'streamIdList' => @streams,
  'includeDefectInstances' => 'true',
  'includeHistory' => 'true',
};
Run Code Online (Sandbox Code Playgroud)

相当于此

my $stream_defect_filter_spec = {
  'streamIdList' => $streams[0],
  $streams[1] => $streams[2],
  $streams[3] => $streams[4],
  ...
  'includeDefectInstances' => 'true',
  'includeHistory' => 'true',
};
Run Code Online (Sandbox Code Playgroud)

所以我希望你能看到,如果数组中有偶数个元素,你会得到警告.

要解决问题,你需要将hash元素的值作为数组引用,这是一个标量,不会扰乱事物的方案

my $stream_defect_filter_spec = {
  'streamIdList' => \@streams,
  'includeDefectInstances' => 'true',
  'includeHistory' => 'true',
};
Run Code Online (Sandbox Code Playgroud)

这样你可以访问数组元素

$stream_defect_filter_spec->{streamIdList}[0]
Run Code Online (Sandbox Code Playgroud)

等等

顺便说一句,你可以通过map做出擅长的事情来大大整理你的代码:

if (ref $x eq 'HASH') {
  push @streams, $x->{id};
}
elsif (ref $x eq 'ARRAY') {
  push @streams, map $_->{id}, @$x;
}
Run Code Online (Sandbox Code Playgroud)


jm6*_*666 8

作业分配:

my $stream_defect_filter_spec = {
        'streamIdList' => @streams,    # <---- THIS ONE
        'includeDefectInstances' => 'true',
        'includeHistory' => 'true',
};
Run Code Online (Sandbox Code Playgroud)

如果不正确,您可以从1 3 5th ...数组元素中获取哈希键.

您可能希望分配对数组的引用,而不是数组本身:

'streamIdList' => \@streams,
Run Code Online (Sandbox Code Playgroud)

不需要的示例(如代码中所示):

use strict;
use warnings;
use Data::Dump;

my @z = qw(a b c x y z);
dd \@z;

my $q = {
    'aa' => @z,
};
dd $q;
Run Code Online (Sandbox Code Playgroud)

不需要的结果

["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
Run Code Online (Sandbox Code Playgroud)

分配参考的示例

use strict;
use warnings;
use Data::Dump;

my @z = qw(a b c x y z);
dd \@z;

my $q = {
    'aa' => \@z,
};
dd $q;
Run Code Online (Sandbox Code Playgroud)

生产:

["a", "b", "c", "x", "y", "z"]
{ aa => ["a", "b", "c", "x", "y", "z"] }
Run Code Online (Sandbox Code Playgroud)

差异清晰可见.