2009-02-18 12 views
7

Sto inviando una subroutine un hash, e il recupero con my($arg_ref) = @_;

Ma che cosa è esattamente %$arg_ref? %$ dereferenziare l'hash?

risposta

17

$arg_ref è uno scalare poiché utilizza il sigillo $. Presumibilmente, contiene un riferimento all'hash. Quindi sì, i deferenze %$arg_ref con riferimento ad hash. Un altro modo per scriverlo è %{$arg_ref}. Questo rende l'intento del codice un po 'più chiaro, anche se più dettagliato.

di citare perldata(1):

Scalar values are always named with '$', even when referring 
to a scalar that is part of an array or a hash. The '$' 
symbol works semantically like the English word "the" in 
that it indicates a single value is expected. 

    $days    # the simple scalar value "days" 
    $days[28]   # the 29th element of array @days 
    $days{'Feb'}  # the 'Feb' value from hash %days 
    $#days    # the last index of array @days 

Così il vostro esempio può essere:

 %$arg_ref   # hash dereferenced from the value "arg_ref" 

my($arg_ref) = @_; afferra la prima voce in stack e posti in una variabile locale chiamata $arg_ref argomento della funzione. Il chiamante è responsabile del passaggio di un riferimento hash. Un modo più canonico di scrivere che è:

my $arg_ref = shift; 

per creare un riferimento hash si potrebbe iniziare con un hash:

some_sub(\%hash); 

Oppure si può creare con un riferimento hash anonimo:

some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation. 
+0

Il prototipo può essere utilizzato per rimuovere la responsabilità di passaggio del riferimento dal chiamante. – chaos

+0

Non penso che insegnare la prototipazione dei nuovi programmatori Perl sia una buona idea. Era una grande barriera proveniente da C e Pascal. Avevo bisogno di imparare il vero valore delle liste di passaggio prima che i prototipi avessero un senso per me. Potrebbe essere utile qui, tuttavia. –

+1

$ sigil non significa una variabile scalare. Significa un valore * scalare *, come in $ hash {chiave} e $ matrice [$ num]. In questo caso è una variabile scalare perché è un valore scalare e non ci sono caratteri di indicizzazione dopo di essa. –

7

Invece di dereferenziare l'intero hash come quello, è possibile afferrare i singoli elementi con

$arg_ref->{key} 
4

Una breve introduzione ai riferimenti (la loro creazione e il loro utilizzo) in Perl è perldoc perfeftut. Puoi anche read it online (o scaricarlo come pdf). (Si parla più di riferimenti in strutture dati complesse che in termini di passaggio dentro e fuori di subroutine, ma la sintassi è la stessa.)

1

Poiché è piuttosto chiaro questo costrutto viene utilizzato per fornire un riferimento hash come un elenco di nome argomenti per un sub va anche notato che questo

sub foo { 
    my ($arg_ref) = @_; 
    # do something with $arg_ref->{keys} 
} 

può essere eccessivo rispetto a solo il disimballaggio @_

sub bar { 
    my ($a, $b, $c) = @_; 
    return $c/($a * $b); 
} 

seconda della complessità la lista degli argomenti è.

2
my %hash = (fred => 'wilma', 
      barney => 'betty'); 
my $hashref = \%hash; 
my $freds_wife = $hashref->{fred}; 
my %hash_copy = %$hash # or %{$hash} as noted above. 

Quindi, qual è il punto della flessibilità della sintassi?Proviamo questo:

my %flintstones = (fred => { wife => 'wilma', 
           kids => ['pebbles'], 
           pets => ['dino'], 
          } 
        barney => { # etc ... } 
       ); 

in realtà per strutture di dati profonde come questo è spesso più conveniente iniziare con un ref:

my $flintstones = { fred => { wife => 'Wilma', 
           kids => ['Pebbles'], 
           pets => ['Dino'], 
           }, 
        }; 

OK, Fred si fa un nuovo animale domestico, 'Velociraptor'

push @{$flintstones->{fred}->{pets}}, 'Velociraptor'; 

Quanti animali ha Fred?

scalare @ {Flintstones -> {fred} -> {animali}}

Diamo loro da mangiare ...

for my $pet (@ {flintstones->{fred}->{pets} }) { 
    feed($pet) 
} 

e così via. La zuppa di parentesi graffa può sembrare un po 'scoraggiante all'inizio, ma alla fine diventa abbastanza facile gestirli, purché sia ​​coerente nel modo in cui li gestisci.