Wyjaśnimy to szczegółowo pod numerem Intermediate Perl.
Ogólna składnia dla zmiennych wyszukiwań jest:
SIGIL BLOCK INDEXY-THING
Dla prostego skalara, który wygląda tak:
print $ { foo };
Widzieliście pewnie to kiedy trzeba oddzielić nazwę zmiennej z rzeczy otaczających to:
print "abc${foo}def\n";
Jeśli masz tylko identyfikator Perla w bloku i no otaczający bałagan, można pozostawić wyłączony szelki, który jest częsty przypadek:
print $foo;
Jednak jest to samo dla dereferencji odniesienie:
SIGIL BLOCK-RETURNING-REFERENCE INDEXY-THINGS
Jeśli sprawa, że pojawi się w blok jest odniesieniem, Perl próbuje dereference nim jak poprosiłeś go zbyt:
my $ref = \ '12345';
print $ { $ref };
to prawdziwy blok choć i to nie tylko cukier. Można mieć wiele sprawozdań, jak chcesz się tam:
print $ { my $ref = \ '1234'; $ref };
Teraz jesteś nie tylko podając identyfikator Perl, więc Perl nie zakładamy, że dajesz mu identyfikator i wykonuje kod i wykorzystuje wynik jako odniesienie. Rozważmy różnicę między tymi niemal identycznych say
oświadczenia:
use 5.010;
our $foo = "I'm the scalar";
sub foo { \ "I'm the sub" }
say ${foo};
say ${foo;};
w tym drugim say
Perl widzi średnik, zdaje sobie sprawę, że nie jest to identyfikator, interpretuje kod wewnątrz szelki jak tekst i zwraca wynik. Ponieważ wynikiem jest odwołanie, używa on ${...}
do dereferencji. Nie ma znaczenia, gdzie to robisz, więc robisz to w ciągu cudzysłowu nie jest wyjątkowy.
Zwróć też uwagę na our
. To ważne, że teraz masz zamiar rozważyć coś nieco bardziej skomplikowane:
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 tej ostatniej say
jako kod i widzi wynik nie jest punktem odniesienia; to prosty ciąg foo
. Perl widzi, że nie jest to odniesienie, ale teraz znajduje się w kontekście dereferencyjnym, więc robi symboliczne odniesienie (jako Greg Bacon describes). Ponieważ odniesienia symboliczne działają ze zmiennymi w tabeli symboli, ta $foo
musi być zmienną pakietową.
Ponieważ łatwo to zepsuć, strict
ma przydatny czek na to. Jednak kiedy go wyłączysz, nie zdziw się, kiedy Cię ugryzie. :)
Wyraźnie stwierdziliście, że chcecie użyć referencji symbolicznych, a "perl" złożyło Waszą ofertę. –
W ten sposób działa dereferencja. Pomocne może okazać się: http://perlmonks.org/?node=References+quick+reference – ysth