【问题标题】:odd number of elements in anonymous hash匿名哈希中的奇数个元素
【发布时间】:2012-07-20 15:42:44
【问题描述】:

我正在尝试理解这个 Perl 代码...

如果有一个流它可以工作,如果有 2 个或更多流它会警告匿名哈希中的奇数个元素。在这种情况下,它似乎返回了一个数组。如何将数组元素正确添加到@streams?它似乎在 if 子句中正确添加了 HASH 案例。 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:Server: calling getStreamDefects: No stream found 对于名称空。 $VAR1 = -1; 我 在 xyz-handler.pl 第 317 行使用“strict refs”时,不能使用字符串(“-1”)作为 HASH ref。

一些 Dumper 输出

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

                          }
                        ],
      'includeDefectInstances' => 'true',
      'includeHistory' => 'true'
    };

【问题讨论】:

    标签: perl


    【解决方案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 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"] }
      

      区别很明显。

      【讨论】:

      • 请再次查看答案。仍然有问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-19
      相关资源
      最近更新 更多