2013-08-11 4 views
15

Qual è il modo migliore per inviare più array, variabili, hash a una subroutine?Passaggio di matrice, scalare e hash alla subroutine in Perl

Forma semplice, funziona.

my $msg = &getMsg(1,2,3); 
print $msg; 

sub getMsg { 
    my($a, $b, $c) = @_; 
} 

Sto avendo difficoltà con questa versione e non sono sicuro di come inviare i dati in modo sicuro alla subroutine senza utilizzare un globale che non è quello che voglio fare.

my @array = ('a','b','c'); 
my $str = "Hello"; 
my %hash = (
    'a' => ['100','nuts'], 
    'b' => ['200','bolts'], 
    'c' => ['300','screws'], 
); 

my $msg = getMsg(@array, $str, %hash); 
print $msg; 

sub getMsg { 
    my (@a, $s, %h) = @_; 
    my $MSG; 
    foreach my $x (@a) { 
     $MSG .= "\n$str, $x your hash value = $h{$x}[0] $h{$x}[1]"; 
    } 
    return $MSG 
} 

risposta

21

È possibile utilizzare i riferimenti:

getMsg(\@array, \%hash, $scalar); 

sub getMsg { 
    my ($aref, $href, $foo) = @_; 
    for my $elem (@$aref) { 
     ... 
    } 
} 

osservare che l'assegnazione si è tentato:

my (@a, $s, %h) = @_; 

Non funziona, perché @a - essendo una matrice - si slurp il intero elenco, lasciando $s e %h non inizializzato.

+0

Si noti che l'hashref passato deve essere dereferenziato quando viene utilizzato nel sotto '$ MSG. =" \ N $ str, $ x il valore hash = $ h -> {$ x} -> [0] $ h- > {$ x} -> [1] "; ' – BarneySchmale

5

preferisco la risposta di TLP, ma si può anche utilizzare un prototipo:

getMsg(@array, %hash, $scalar); 

sub getMsg (\@\%$) { 
    my ($aref, $href, $foo) = @_; 
    for my $elem (@$aref) { 
     ... 
    } 
} 

Il prototipo (\@\%$) costringe gli argomenti alla chiamata di subroutine a un riferimento di lista, un riferimento hash, e uno scalare prima la gli argomenti vengono appiattiti e caricati in @_. All'interno della subroutine, si riceve un riferimento elenco e un riferimento hash invece di un array e un hash.

Di solito, tuttavia, don't use prototypes.