Sto inviando una subroutine un hash, e il recupero con my($arg_ref) = @_;
Ma che cosa è esattamente %$arg_ref
? %$
dereferenziare l'hash?
Sto inviando una subroutine un hash, e il recupero con my($arg_ref) = @_;
Ma che cosa è esattamente %$arg_ref
? %$
dereferenziare l'hash?
$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.
Invece di dereferenziare l'intero hash come quello, è possibile afferrare i singoli elementi con
$arg_ref->{key}
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.)
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 è.
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.
Il prototipo può essere utilizzato per rimuovere la responsabilità di passaggio del riferimento dal chiamante. – chaos
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. –
$ 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. –