2012-07-21 28 views
10

che sto cercando di capire questo codice Perl ...numero dispari di elementi in hash anonimo

Se c'è un flusso che funziona, se ci sono 2 o più flussi avverte con un numero dispari di elementi in forma anonima hash. Sembra che restituisca una matrice in quel caso. Come aggiungo correttamente gli elementi dell'array a @streams? Sembra aggiungere correttamente il caso HASH nella clausola if. La cotta della clausola 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); 

sto aggiungendo le prossime righe ...

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).")"; 
    } 

Ora gli errori con API

Web ha restituito il codice di errore S: Server: chiamando getStreamDefects: Nessun flusso trovato per nome nullo. $ VAR1 = -1; me Impossibile utilizzare stringa ("-1") come Rif HASH mentre "strict refs" in uso presso la linea 317. xyz-handler.pl

qualche uscita Dumper

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

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

risposta

14

L'elenco assegnato ad un hash è un insieme di coppie chiave/valore, motivo per cui il numero di elementi deve essere pari.

Perché l'operatore => è poco più di una virgola, e l'array @streams è appiattito nella lista, questo

my $stream_defect_filter_spec = { 
    'streamIdList' => @streams, 
    'includeDefectInstances' => 'true', 
    'includeHistory' => 'true', 
}; 

è equivalente a questa

my $stream_defect_filter_spec = { 
    'streamIdList' => $streams[0], 
    $streams[1] => $streams[2], 
    $streams[3] => $streams[4], 
    ... 
    'includeDefectInstances' => 'true', 
    'includeHistory' => 'true', 
}; 

quindi spero che si può vedere che riceverai l'avviso se hai uno numero di elementi nella matrice.

di sistemare le cose è necessario il valore dell'elemento hash per essere un array di riferimento , che è uno scalare e non sconvolgerà schema delle cose

my $stream_defect_filter_spec = { 
    'streamIdList' => \@streams, 
    'includeDefectInstances' => 'true', 
    'includeHistory' => 'true', 
}; 

questo modo è possibile accedere alla matrice elementi come

$stream_defect_filter_spec->{streamIdList}[0] 

ecc

e tra l'altro è possibile riordinare il codice sostanzialmente lasciando map fare ciò che è bravo a:

if (ref $x eq 'HASH') { 
    push @streams, $x->{id}; 
} 
elsif (ref $x eq 'ARRAY') { 
    push @streams, map $_->{id}, @$x; 
} 
6

L'assegnazione in:

my $stream_defect_filter_spec = { 
     'streamIdList' => @streams, # <---- THIS ONE 
     'includeDefectInstances' => 'true', 
     'includeHistory' => 'true', 
}; 

non è corretto, si ottiene chiavi hash dal 1 3 5 ° ... una serie di elementi.

Probabilmente si desidera assegnare un riferimento ad array, non l'array stesso:

'streamIdList' => \@streams, 

esempio per gli indesiderati (come nel codice):

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

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

my $q = { 
    'aa' => @z, 
}; 
dd $q; 

risultato indesiderato:

["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 

Esempio di assegnazione di un riferimento

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

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

my $q = { 
    'aa' => \@z, 
}; 
dd $q; 

produce:

["a", "b", "c", "x", "y", "z"] 
{ aa => ["a", "b", "c", "x", "y", "z"] } 

La differenza è chiaramente visibile.

+0

pls rivedere la risposta. ancora il problema –

+0

@DB, ha aggiunto entrambi gli esempi. – jm666

Problemi correlati