Spieghiamo questo in profondità in Intermediate Perl.
La sintassi generale per le ricerche variabili è:
SIGIL BLOCK INDEXY-THING
Per un semplice scalare che assomiglia a:
print $ { foo };
probabilmente avete visto questo quando è necessario separare un nome di variabile dalle cose circostanti it:
print "abc${foo}def\n";
Se si dispone solo di un identificativo Perl nel blocco e nessun disordine circostante, è possibile lasciare fuori le parentesi graffe, che è il caso comune:
print $foo;
Tuttavia, questa è la stessa cosa per dereferencing un riferimento:
SIGIL BLOCK-RETURNING-REFERENCE INDEXY-THINGS
Se la cosa che si ottiene in il blocco è un riferimento, Perl cerca di dereferenziarlo come hai chiesto troppo:
my $ref = \ '12345';
print $ { $ref };
Questo è un vero e proprio blocco, però, e non solo lo zucchero. Si può avere il maggior numero di affermazioni che vuoi in là:
print $ { my $ref = \ '1234'; $ref };
Ora non sei solo specificando un identificatore di Perl, quindi Perl non si assume che si sta dando un identificatore ed esegue il codice e gli usi il risultato come riferimento. Si consideri la differenza tra questi quasi identiche say
dichiarazioni:
use 5.010;
our $foo = "I'm the scalar";
sub foo { \ "I'm the sub" }
say ${foo};
say ${foo;};
In quel secondo say
Perl vede il punto e virgola, si rende conto che non è un identificatore, interpreta il codice all'interno delle parentesi come testo, e restituisce il risultato. Poiché il risultato è un riferimento, utilizza lo ${...}
per dereferenziarlo. Non importa dove lo fai, in modo che lo fai all'interno di una stringa doppia citazione non è speciale.
Inoltre, notare lo our
lì. Questo è importante, ora che si sta andando a prendere in considerazione qualcosa di un po 'più complicato:
use 5.010;
our $foo = "I'm the scalar";
sub foo { \ "I'm the sub" }
sub baz { 'foo' }
say ${foo};
say ${foo;};
say ${baz;};
Perl intreprets che lo scorso say
come codice e vede il risultato non è un punto di riferimento; è la semplice stringa foo
. Perl vede che non è un riferimento ma è ora in un contesto di dereferenziazione, quindi fa un riferimento simbolico (come Greg Bacon describes). Poiché i riferimenti simbolici funzionano con variabili nella tabella dei simboli, che $foo
doveva essere una variabile di pacchetto.
Dal momento che è facile incasinare, strict
ha un controllo pratico per questo. Tuttavia, quando lo spegni, non essere sorpreso quando ti morde. :)
Hai esplicitamente dichiarato che volevi utilizzare i riferimenti simbolici e 'perl' ha fatto la tua offerta. –
Ecco come funziona il dereferenziamento. Potresti trovare utile: http://perlmonks.org/?node=References+quick+reference – ysth