Provided by: manpages-pl_20060617-2_all bug

NAZWA

       perlref - odwołania i zagnieżdżone struktury danych w Perlu

UWAGA

       To jest pełna dokumentacja dotycząca wszelkich aspektów odwołań.
       Krótszy, wprowadzający wstęp to najistotniejszych cech znajdziesz w
       podręczniku perlreftut(1).

OPIS

       Przed wersją 5 Perla przedstawianie złożonych struktur danych było
       trudne, gdyż wszystkie odwołania musiały być symboliczne -- a nawet
       wtedy ciężko było odnosić się do zmiennej zamiast do pozycji w tablicy
       symboli.  Obecnie Perl nie tylko ułatwia posługiwanie się symbolicznymi
       odwołaniami do zmiennych, ale także pozwala na użycie "stałych" odwołań
       (hard references) do dowolnego kawałka danych lub kodu. Stałe
       dowiązanie może być przechowywane w dowolnym skalarze. Ponieważ tablice
       i tablice asocjacyjne (hasze) zawierają skalary, to możesz teraz łatwo
       budować tablice tablic, tablice haszy, hasze tablic, tablice haszy
       funkcji i tak dalej.

       Odwołania stałe są sprytne -- utrzymują za ciebie liczniki odwołań,
       automatycznie zwalniając rzecz, do której odnosi się odwołanie, jeśli
       jej licznik odwołań zejdzie do zera. (Uwaga: liczniki odwołań dla
       wartości w strukturach danych odnoszących się do samych na siebie
       (self-referential) lub strukturach cyklicznych mogą nie schodzić do
       zera bez pewnej drobnej pomocy; patrz sekcja Two-Phased Garbage
       Collection w podręczniku perlobj(1), zawierająca bardziej szczegółowy
       opis.)  Jeśli taka rzecz jest obiektem, to obiekt jest niszczony.
       Więcej o obiektach znajdziesz w podręczniku perlobj(1). (W pewnym
       sensie, wszystko w Perlu jest obiektem, ale zwykle rezerwujemy to słowo
       dla odwołań do obiektów, które zostały oficjalnie "pobłogosławione"
       ("blessed") [tj.zakwalifikowane jako obiekty] w pakiecie klasy.)

       Odwołania symboliczne są nazwami zmiennych lub innych obiektów;
       zupełnie tak jak dowiązania symboliczne (symbolic links) w uniksowym
       systemie plików zawierają wyłącznie nazwę pliku. Notacja *glob jest
       rodzajem odwołania symbolicznego.  (Odwołania symboliczne nazywane są
       czasami "soft references" [odwołaniami miękkimi, w przeciwieństwie do
       "hard r."-"twardych"], ale proszę nie nazywaj ich tak; odwołania są
       wystarczająco zbijające z pantałyku bez zbędnych synonimów.)

       W przeciwieństwie do nich, odwołania stałe przypominają dowiązania
       stałe (hard links) uniksowego systemu plików: służą do udostępniania
       obiektu bez zwracania uwagi na to, jaka jest jego (inna) nazwa. Tam,
       gdzie użyto słowa "odwołanie" bez przymiotnika, jak w poniższym
       akapicie, mówi się zwykle o odwołaniu stałym.

       W Perlu odwołania są łatwe w użyciu. Jest tylko jedna nadrzędna zasada:
       Perl nie wykonuje niejawnego odwoływania bądź dereferowania odwołań.
       [Dereferencing: odniesienie się z powrotem do obiektu, rzeczy na którą
       wskazuje odwołanie].  Gdy skalar przechowuje odwołanie, to zawsze
       zachowuje się jak zwykły skalar.  Nie zaczyna magicznie być tablicą,
       haszem czy procedurą; musisz wprost nakazać takie zachowanie, wykonując
       dereferencję.

       Tworzenie odwołań

       Odwołania mogą być tworzone na kilka sposobów.

       1.  Przez zastosowanie operatora odwróconego ukośnika do zmiennej,
           procedury lub wartości. (Działa to bardzo podobnie do operatora &
           (zwracającego adres) w języku C.) Zauważ, że konstrukcja ta tworzy
           KOLEJNE odwołanie do zmiennej, gdyż w tablicy symboli istnieje już
           odwołanie do tej zmiennej.  Jednak odwołanie z tablicy symboli może
           zniknąć, a nadal będziesz mieć odwołanie, które zwrócił odwrócony
           ukośnik. Oto kilka przykładów:

               $scalarref = \$foo;
               $arrayref  = \@ARGV;
               $hashref   = \%ENV;
               $coderef   = \&handler;
               $globref   = \*foo;

           Przy użyciu operatora odwróconego ukośnika nie jest możliwe
           utworzenie prawdziwego odwołania do uchwytu IO (uchwytu pliku lub
           katalogu).  Możesz co najwyżej uzyskać odwołanie do typeglob
           będącego faktycznie pełnym wpisem w tablicy symboli. (Przeczytaj
           jednak poniżej objaśnienie składni *foo{COŚ}.) Mimo to, możesz
           nadal używać typeglob i odwołań do nich jakby były one uchwytami
           IO.

       2.  Odwołanie do anonimowej tablicy można stworzyć posługując się
           nawiasami kwadratowymi:

               $arrayref = [1, 2, ['a', 'b', 'c']];

           Utworzyliśmy odwołanie do anonimowej tablicy trzech elementów,
           której ostatni element jest z kolei odwołaniem do innej anonimowej
           tablicy trzech elementów.  (Dostęp do niej umożliwi opisana dalej
           składnia tablic wielowymiarowych.  Na przykład, dla powyższego
           przykładu $arrayref->[2][1] zwraca wartość "b".)

           Zauważ, że stworzenie odwołania do listy wyliczanej nie jest tym
           samym, co użycie nawiasów kwadratowych. Jest to natomiast tym
           samym, co stworzenie listy odwołań!

               @list = (\$a, \@b, \%c);
               @list = \($a, @b, %c);      # to samo!

           W przypadku szczególnym, \(@foo) zwraca listę odwołań do zawartości
           @foo, nie zaś odwołanie do samej @foo. Podobnie jest dla %foo, z
           wyjątkiem tego, że odwołania-klucze odnoszą się do kopii (gdyż
           klucze są łańcuchami znakowymi, a nie dowolnymi skalarami).

       3.  Odwołanie do anonimowej tablicy asocjacyjnej (hasza) można utworzyć
           używając nawiasów klamrowych:

               $hashref = {
                   'Adam'  => 'Ewa',
                   'Clyde' => 'Bonnie',
               };

           Powyższe konstruktory anonimowych haszy i tablic można swobodnie
           łączyć.  Umożliwia to otrzymywanie dowolnie skomplikowanych
           struktur.  Opisana składnia wielowymiarowych tablic/haszy działa
           także dla nich.  Wartości w powyższym przykładzie były literałami,
           ale równie dobrze mogłyby być zmiennymi czy wyrażeniami, gdyż
           perlowe operatory przypisania (nawet wewnątrz local() czy my()) są
           wykonywalnymi instrukcjami, a nie jedynie deklaracjami dla fazy
           kompilacji.

           Ponieważ nawiasy klamrowe służą do kilku innych rzeczy, a także do
           tworzenia BLOKów, możesz być czasem zmuszony do uniknięcia
           dwuznaczności tych nawiasów na początku instrukcji. Wystarczy
           wówczas umieszczenie przed nimi + lub return, by Perl zorientował
           się, że otwierający nawias klamrowy nie rozpoczyna BLOKu.
           Oszczędność i zalety mnemoniczne użycia nawiasów klamrowych warte
           są takiego sporadycznego zamieszania.

           Na przykład, jeśli chciałbyś, by funkcja tworzyła nowy hasz i
           zwracała odwołanie do niego, to masz takie możliwości:

               sub hashem {        { @_ } }   # źle, ale bez komunikatu o błędzie
               sub hashem {       +{ @_ } }   # ok
               sub hashem { return { @_ } }   # ok

           Z drugiej strony, jeśli chcesz drugiego znaczenia nawiasów (blok),
           zrób tak:

               sub showem {        { @_ } }   # dwuznaczne (obecnie ok, ale może się zmienić)
               sub showem {       {; @_ } }   # ok
               sub showem { { return @_ } }   # ok

           Zwróć uwagę, że początkowe +{ i {; zawsze służą do wykluczenia
           dwuznaczności wyrażenia, aby znaczyło albo odwołanie do HASZa albo
           BLOK.

       4.  Można utworzyć odwołanie do anonimowej procedury używając sub bez
           nazwy procedury:

               $coderef = sub { print "Bums!\n" };

           Zwróć uwagę na obecność średnika.  Poza faktem, że wewnętrzny kod
           nie jest wykonywany natychmiast, sub {} jest bardziej operatorem
           niż deklaracją, podobnie zresztą jak do{} czy eval{}.  (Jednak,
           niezależnie od tego, ile razy wykonasz powyższą linię (chyba że
           jesteś wewnątrz eval("...")), $coderef wciąż będzie zawierać
           odwołanie do TEJ SAMEJ anonimowej procedury.)

           Procedury anonimowe działają jak zamknięcia (closures) w
           odniesieniu do zmiennych my(), to znaczy, zmiennych widocznych
           leksykalnie w bieżącym zakresie. Zamknięcie jest pojęciem ze świata
           Lispa, mówiącym, że jeśli zdefiniujesz anonimową funkcję w
           konkretnym kontekście leksykalnym, to będzie ona działać w tym
           kontekście nawet jeśli została wywołana poza nim.

           Mówiąc po ludzku, jest to zabawny sposób przesyłania argumentów do
           procedury zarówno gdy ją definiujesz jak i wtedy gdy ją wywołujesz.
           Przydaje się to do tworzenia małych fragmentów kodu do późniejszego
           uruchamiania, jak np. wywołania wsteczne (callbacks). Przy ich
           pomocy możesz robić nawet rzeczy zorientowane obiektowo, choć Perl
           zapewnia już odmienny mechanizm operowania obiektami --patrz
           podręcznik perlobj(1).

           Możesz również myśleć o zamknięciach jak o sposobie pisania
           szablonów bez używania eval. (Faktycznie, w wersji 5.000, eval było
           jedyn metodą uzyskania zamknięć. Jeśli posługujesz się
           zamknięciami, możesz potrzebować "require 5.001".)

           A to mały przykład tego, jak działają zamknięcia:

               sub newprint {
                   my $x = shift;
                   return sub { my $y = shift; print "$x, $y!\n"; };
               }
               $h = newprint("Howdy");
               $g = newprint("Greetings");

               # czas mija...

               &$h("world");
               &$g("earthlings");

           Drukuje to

               Howdy, world!
               Greetings, earthlings!

           Zwróć uwagę szczególnie na to, że $x nadal odnosi się do wartości
           przesłanej do newprint(), mimo e zmienna "my $x" pozornie wyszła
           poza swój zakres, w momencie gdy wywołano anonimową procedurę. O to
           właśnie chodzi w zamknięciu.

           Przy okazji: odnosi się do tylko do zmiennych leksykalnych. Zmienne
           dynamiczne działają nadal tak jak zawsze. Zamknięcie nie jest
           czymś, o co musiałaby się martwić większość programistów Perla.

       5.  Odwołania często zwracane są przez specjalne procedury zwane
           konstruktorami.  Obiekty w Perlu są po prostu odwołaniami do
           specjalnego rodzaju obiektu, który wie z którym pakietem jest
           związany. Konstruktory są specjalnymi procedurami, które wiedzą jak
           utworzyć to powiązanie.  Robią to zaczynając od zwykłego odwołania,
           i pozostaje ono zwykłym odwołaniem nawet wtedy gdy jest
           równocześnie obiektem. Konstuktory często nazywane są new() i
           wywoływane nie wprost:

               $objref = new Psisko (Ogon => 'krótki', Uszy => 'długie');

           Ale nie muszą być:

               $objref   = Psisko->new(Ogon => 'krótki', Uszy => 'długie');

               use Term::Cap;
               $terminal = Term::Cap->Tgetent( { OSPEED => 9600 });

               use Tk;
               $main    = MainWindow->new();
               $menubar = $main->Frame(-relief              => "raised",
                                       -borderwidth         => 2)

       6.  Odwołania odpowiedniego typu mogą być powoływane do istnienia jeśli
           dereferencjonujesz je w kontekście zakładającym, że istnieją.
           Ponieważ jeszcze nie mówiliśmy o dereferencji, nie możemy na razie
           pokazać przykładów.

       7.  Odwołanie może być utworzone przy pomocy specjalnej składni, uroczo
           zwanej składnią *foo{COŚ}.  *foo{COŚ} zwraca odwołanie do
           przegródki COŚ w *foo (które jest pozycją w tablicy symboli
           przechowującą wszystko znane jako foo.)

               $scalarref = *foo{SCALAR};
               $arrayref  = *ARGV{ARRAY};
               $hashref   = *ENV{HASH};
               $coderef   = *handler{CODE};
               $ioref     = *STDIN{IO};
               $globref   = *foo{GLOB};

           Wszystkie powyższe wyrażenia są oczywiste, z wyjątkiem *foo{IO}.
           Zwraca ono uchwyt IO, używany jako uchwyt pliku (patrz opis open w
           podręczniku perlfunc(1)), gniazdo (opis socket oraz socketpair w
           perlfunc(1)) lub uchwyt katalogu (opendir w perlfunc(1)). Dla
           zgodności z poprzednimi wersjami Perla, *foo{UCHWYTPLIKU} jest
           synonimem *foo{IO}.

           *foo{COŚ} zwraca undef jeśli dane COŚ jeszcze nie było używane, z
           wyjątkiem dla skalarów. Jeśli nie używano jeszcze $foo,
           *foo{SKALAR} zwraca odwołanie do anonimowego skalara.  W przyszłych
           wersjach może się to zmienić.

           *foo{IO} jest alternatywą dla mechanizmu \*UCHWYTU opisanego w
           sekcji Typeglobs and Filehandles podręcznika perldata(1), a
           służącego do przesyłania uchwytów plików do i z procedur lub
           przechowywania w większych strukturach danych. Jego wadą jest to,
           że nie utworzy za Ciebie nowego uchwytu pliku. Zaletą zaś, że nie
           ryzykujesz więcej niż zamierzałeś przy przypisaniem typeglob, choć
           jeśli wykonasz przypisanie do skalara zamiast do typeglob, to też
           dobrze.

               splutter(*STDOUT);
               splutter(*STDOUT{IO});

               sub splutter {
                   my $fh = shift;
                   print $fh "her um well a hmmm\n";
               }

               $rec = get_rec(*STDIN);
               $rec = get_rec(*STDIN{IO});

               sub get_rec {
                   my $fh = shift;
                   return scalar <$fh>;
               }

       Posługiwanie się odwołaniami

       To tyle o tworzeniu odwołań. Teraz pewnie nie możesz się doczekać
       wiedzy jak posługiwać się odwołaniami, by móc wrócić do swych leżących
       odłogiem danych.  Oto kilka podstawowych sposobów.

       1.  Wszędzie, gdzie postawiłbyś identyfikator (lub łańcuch
           identyfikatorów) jako część nazwy zmiennej czy procedury, możesz
           zastąpić identyfikator prostą zmienną skalarną zawierającą
           odwołanie poprawnego typu:

               $bar = $$scalarref;
               push(@$arrayref, $nazwapliku);
               $$arrayref[0] = "styczeń";
               $$hashref{"KLUCZ"} = "WARTOŚĆ";
               &$coderef(1,2,3);
               print $globref "wynik\n";

           Ważne jest, by zrozumieć, że nie NIE wykonujemy tu specjalnie
           dereferencji $arrayref[0] czy $hashref{"KLUCZ"}.  Dereferencja
           zmiennej skalarnej odbywa się PRZED przeszukaniem klucza (indeksu
           tablicy). Wszystko bardziej skomplikowane niż dereferencja prostej
           zmiennej skalarnej wymaga użycia niżej opisanych metod 2 lub 3.
           Jednak określenie "prosty skalar" obejmuje też identyfikator, który
           sam używa rekurencyjnie metody 1. Zatem poniższe drukuje "witaj".

               $refrefref = \\\"witaj";
               print $$$$refrefref;

       2.  Wszędzie, gdzie postawiłbyś identyfikator (lub łańcuch
           identyfikatorów) jako część nazwy zmiennej czy procedury, możesz
           zastąpić identyfikator BLOKiem zwracającym odwołanie poprawnego
           typu. Inaczej mówiąc, poprzednie przykłady mogą zostać zapisane
           tak:

               $bar = ${$scalarref};
               push(@{$arrayref}, $nazwapliku);
               ${$arrayref}[0] = "styczeń";
               ${$hashref}{"KLUCZ"} = "WARTOŚĆ";
               &{$coderef}(1,2,3);
               $globref->print("wynik\n");  # jeśli załadowano IO::Handle

           Niewątpliwie, użycie nawiasów klamrowych w tym przypadku nie jest
           zbyt mądre, ale BLOK może zawierać dowolne wyrażenie, w
           szczególności wyrażenia indeksowane:

               &{ $dispatch{$index} }(1,2,3);      # wywołaj właściwą obsługę

           Z powodu możliwości pomijania nawiasów klamrowych dla prostych
           przypadków $$x, ludzie często popełniają błąd postrzegania symboli
           dereferencji jako prawdziwych operatorów i zastanawiają się nad ich
           priorytetem.  Gdyby nimi były, mógłbyś używać zwykłych nawiasów
           zamiast klamrowych.  Tak jednak nie jest. Rozważ poniższą różnicę:
           przypadek 0 jest skróconą wersją przypadku 1, NIE przypadku 2:

               $$hashref{"KLUCZ"}   = "WARTOŚĆ";       # przypadek 0
               ${$hashref}{"KLUCZ"} = "WARTOŚĆ";       # przypadek 1
               ${$hashref{"KLUCZ"}} = "WARTOŚĆ";       # przypadek 2
               ${$hashref->{"KLUCZ"}} = "WARTOŚĆ";     # przypadek 3

           Przypadek 2 jest również mylący, gdyż odnosi się do zmiennej o
           nazwie %hashref, nie zaś dereferencjonuje poprzez $hashref hasza,
           na który wydawałoby się wskazuje skalar. To robi przypadek 3.

       3.  Wywołania procedur i poszukiwanie poszczególnych elementów tablic
           pojawiają się wystarczająco często, by zastosowanie do nich metody
           2 stało się niewygodne.  Jako formę "osłodzenia składni", przykłady
           z metody 2 można zapisać:

               $arrayref->[0] = "styczeń";        # element tablicy
               $hashref->{"KLUCZ"} = "WARTOŚĆ";   # element hasza
               $coderef->(1,2,3);                 # wywołanie procedury

           Lewa strona strzałki może być dowolnym wyrażeniem zwracającym
           odwołanie, łącznie z uprzednią dereferencją. [Ułatwia to operowanie
           odwołaniami do zmiennych zawierających kolejne odwołania, jak
           poniżej].  Zauważ, że $array[$x] NIE jest tu tym samym co
           $array->[$x]:

               $array[$x]->{"foo"}->[0] = "styczeń";

           Jest to jeden z przypadków wspomnianych wcześniej, gdzie odwołania
           zaistnieją, gdy zostaną użyte w kontekście l-wartości. Przed tą
           instrukcją, element $array[$x] mógł być niezdefiniowany. W takim
           przypadku, jest on definiowany automatycznie z nadaniem mu wartości
           -- odwołania do hasza, tak że możemy poszukiwać w haszu elementu o
           kluczu "foo".  Podobnie klucz $array[$x]->{"foo"} zostanie
           automatycznie zdefiniowany z równoczesnym nadaniem wartości --
           odwołania do tablicy, zatem będzie można w niej odnaleźć [0].
           Proces ten zwany jest autovivification (automatyczne ożywianie).

           Jeszcze jedno. POMIDZY indeksami umieszczonymi w nawiasach
           klamrowych strzałka jest opcjonalna, zatem możemy skrócić powyższy
           zapis do:

               $array[$x]{"foo"}[0] = "styczeń";

           Co, w szczególnym przypadku działania tylko na zwykłych tablicach,
           daje tablice wielowymiarowe z zapisem jak w C:

               $score[$x][$y][$z] += 42;

           No dobrze, tak naprawdę, nie całkiem jak tablice w C. C nie wie,
           jak poszerzać tablice na żądanie. Perl to potrafi.

       4.  Jeżeli odwołanie jest odwołaniem do obiektu, to prawdopodobnie
           istnieją metody dostępu do wskazywanych przez nie rzeczy, i
           powinieneś zapewne z nich skorzystać, chyba że jesteś w pakiecie
           klasy definiującej metody tego obiektu i pracujesz nad nimi.
           Inaczej mówiąc, bądź tak dobry i nie naruszaj hermetyzacji bez
           istotnego powodu. Perl nie wymusza hermetyzacji. Nie jesteśmy tu
           totalitarystami.  Oczekujemy jednak zachowania podstawowych zasad
           uprzejmości.

       Można posłużyć się operatorem ref() do stwierdzenia, na jaki typ rzeczy
       wskazuje odwołanie. Zobacz podręcznik perlfunc(1).

       Operator bless() może być używany do powiązania obiektu, na który
       wskazuje odwołanie, z pakietem funkcjonującym jako klasa obiektowa.
       Zobacz podręcznik perlobj(1).

       Typeglob może być dereferencjowane w ten sam sposób jak odwołanie, gdyż
       składnia dereferencji zawsze wskazuje na pożądany rodzaj odwołania.
       Zatem ${*foo} i ${\$foo} wskazują na tę samą zmienną skalarną.

       A oto sztuczka do interpolacji wywołania procedury w łańcuchu:

           print "Procedura mysub tym razem zwróciła @{[mysub(1,2,3)]} .\n";

       Działa to w tak, że gdy @{...} znalezione zostanie wewnątrz łańcucha w
       cudzysłowach to zostanie potraktowane jako blok. Blok ten tworzy
       odwołanie do jednoelementowej anonimowej tablicy zawierającej wynik
       wywołania mysub(1,2,3) [odwołanie to utworzone będzie dzięki nawiasom
       kwadratowym].  Zatem cały blok zwraca odwołanie do tablicy, która
       następnie podlega dereferencji powodowanej przez @{...}. Jej wartość,
       jako umieszczona w łańcuchu w cudzysłowach podlega interpolacji w
       napis.  Takie szykany przydają się także w dowolnych wyrażeniach:

           print "That yields @{[$n + 5]} widgets\n";

       Odwołania symboliczne

       Powiedzieliśmy, że niezdefiniowane cele odwołania w razie potrzeby
       zaistnieją [podczas dereferencji].  Nie mówiliśmy jednak, co się
       dzieje, gdy wartość użyta jako odwołanie jest już zdefiniowana, ale NIE
       JEST odwołaniem stałym. Jeżeli użyjesz odwołania w takim przypadku, to
       będzie ono potraktowane jak odwołanie symboliczne. To znaczy, wartością
       skalara zostanie NAZWA zmiennej a nie bezpośrednie dowiązanie do (być
       może anonimowej) wartości.

       Niektórzy często spodziewają się, że działa to jakoś tak. I
       rzeczywiście.

           $name = "foo";
           $$name = 1;                 # ustawia $foo
           ${$name} = 2;               # ustawia $foo
           ${$name x 2} = 3;           # ustawia $foofoo
           $name->[0] = 4;             # ustawia $foo[0]
           @$name = ();                # czyści @foo
           &$name();                   # wywołuje &foo() (jak w Perl 4)
           $pack = "THAT";
           ${"${pack}::$name"} = 5;    # ustawia $THAT::foo bez rozwinięcia(eval)

       Jest to bardzo silne narzędzie, ale nieco niebezpieczne, gdyż możliwe
       jest, ze szczerym zamiarem użycia odwołania stałego, przypadkowe użycie
       symbolicznego. Możesz się przed tym uchronić pisząc:

           use strict 'refs';

       a dla reszty otaczającego bloku będą dozwolone tylko odwołania stałe.
       Wewnętrzny blok może się temu sprzeciwić przy pomocy

           no strict 'refs';

       Dla odwołań symbolicznych widoczne są tylko zmienne pakietu (globalne,
       nawet jeśli lokalnie). Zmienne leksykalne (deklarowane przy pomocy
       my()) nie zawierają się w tablicy symboli, zatem są niewidoczne dla
       tego mechanizmu.  Na przykład:

           local $wartosc = 10;
           $ref = "wartosc";
           {
               my $wartosc = 20;
               print $$ref;
           }

       Nadal będzie drukować 10, a nie 20. Pamiętaj, że local() działa na
       zmienne pakietu, które dla samego pakietu wszystkie są "globalne".

       Odwołania niezbyt symboliczne

       Nową cechą poprawiającą czytelność, wprowadzoną w perlu wersji 5.001,
       jest to, że nawiasy wokół odwołania symbolicznego zachowują się jak
       znaki cudzysłowu, czyli tak, jakby zawsze zawierały wewnątrz łańcuch.
       To znaczy, że

           $push = "pop on ";
           print "${push}over";

       miało zawsze znaczenie wydrukowania "pop on over", bez względu na fakt,
       że "push" jest słowem zarezerwowanym. Zostało to uogólnione tak, by
       działać również poza cudzysłowami, zatem

           print ${push} . "over";

       a nawet

           print ${ push } . "over";

       mają ten sam rezultat. (Spowodowałoby to błąd składni w Perlu 5.000,
       choć Perl 4 dopuszcza coś takiego w postaci bez odstępów.) Zauważ, że
       konstrukcja ta nie nie jest uważana za odwołanie symboliczne gdy
       używasz strict refs:

           use strict 'refs';
           ${ bareword };      # dobrze, znaczy $bareword.
           ${ "bareword" };    # błąd, odwołanie symboliczne.

       Podobnie, z powodu wszelkiego indeksowania przy pomocy pojedynczych
       słów, zastosowaliśmy tę samą regułę do każdego z gołych słów użytego do
       indeksowania hasza. Zatem teraz, zamiast

           $array{ "aaa" }{ "bbb" }{ "ccc" }

       możesz napisać po prostu

           $array{ aaa }{ bbb }{ ccc }

       i nie martwić się o to, czy indeksy są słowami zarezerwowanymi. W tych
       rzadkich przypadkach, gdy chcesz zrobić coś w rodzaju

           $array{ shift }

       możesz wymusić interpretację słowa jako zarezerwowanego dodając
       cokolwiek, co zrobi zeń więcej niż gołe słowo:

           $array{ shift() }
           $array{ +shift }
           $array{ shift @_ }

       Przełącznik -w będzie Cię ostrzegał, jeśli zinterpretuje słowo
       zarezerwowane jako łańcuch. Nie będzie jednak ostrzegał o użyciu słów
       pisanych małymi literami, gdyż łańcuch jest faktycznie cytowany.

       Pseudo-hasze: Używanie tablicy jak hasza

       OSTRZEŻENIE:  Niniejsza sekcja opisuje cechę eksperymentalną.  W
       przyszłych wersjach szczegóły mogą ulec zmianie bez powiadomienia.

       Począwszy od Perla 5.005 możesz w pewnych kontekstach posługiwać się
       odwołaniem do tablicy, mimo że normalnie wymagają one odwołania do
       hasza.  Pozwala to na dostęp do elementów tablicy przy użyciu nazw
       symbolicznych, tak jakby były one polami struktury.

       Żeby to zadziałało tablica musi zawierać dodatkową informację.
       Pierwszym elementem tablicy powinno być odwołanie do hasza
       odwzorowującego nazwy pól na indeksy tablicy. Oto przykład:

          $struct = [{foo => 1, bar => 2}, "FOO", "BAR"];

          $struct->{foo};  # to samo, co $struct->[1], tj. "FOO"
          $struct->{bar};  # to samo, co $struct->[2], tj. "BAR"

          keys %$struct;   # zwróci ("foo", "bar") w jakiejś kolejności
          values %$struct; # zwróci ("FOO", "BAR") w jakiejś kolejności

          while (my($k,$v) = each %$struct) {
              print "$k => $v\n";
          }

       Jeśli spróbujesz usunąć klucze z takiego pseudo-hasza lub będziesz
       próbował sięgnąć do nieistniejących pól, perl zgłosi wyjątek.  W celu
       poprawy wydajności, Perl może też wykonać na etapie kompilacji
       tłumaczenie nazw pól na odpowiadające im indeksy tablicy dla opisanych
       odwołań.  Patrz  podręcznik fields(3).

       Szablony funkcji

       Jak wyjaśniono powyżej, zamknięcie jest anonimową funkcją z dostępem do
       zmiennych  leksykalnych widocznych podczas jej kompilacji. Zachowuje
       ona dostęp do tych zmiennych nawet wtedy, gdy jest wykonywana później,
       tak jak funkcja obsługi sygnału (signal handler) czy wywołanie wsteczne
       Tk.

       Posługiwanie się zamknięciem jako szablonem funkcji umożliwia tworzenie
       wielu podobnie działających funkcji. Załóżmy, że potrzebujesz funkcji o
       nazwach pochodzących od różnych kolorów zmieniających czcionkę HTML.

           print "Hej, ", red("uważaj"), "na to ", green("światło");

       Funkcje red() i green() będą bardzo podobne. By je stworzyć,
       przypiszemy zamknięcie do typeglob nazwy funkcji, którą próbujemy
       skonstruować.

           @kolory = qw(red blue green yellow orange purple violet);
           for my $nazwa (@kolory) {
               no strict 'refs';       # pozwól na operowanie tablicą symboli
               *$nazwa = *{uc $nazwa} = sub { "<FONT COLOR='$nazwa'>@_</FONT>" };
           }

       Teraz wszystkie te funkcje będą istnieć niezależnie od siebie. Możesz
       wywoływać red(), RED(), blue(), BLUE(), green(), etc. Technika ta
       zarówno skraca czas kompilacji jak i zmniejsza zużycie pamięci, jest
       też mniej narażona na błędy, gdyż kontrola składni odbywa się podczas
       kompilacji. Istotne jest, by wszelkie zmienne w anonimowej procedurze
       były zmiennymi leksykalnymi by stworzyć poprawne zamknięcie. Z tego
       powodu użyto my dla zmiennej sterującej pętli.

       Jest to jedno z jedynych miejsc, gdzie dostarczenie prototypu do
       zamknięcia ma sens. Jeśli chciałbyś narzucić kontekst skalarny dla
       argumentów powyższych, przykładowych funkcji (pewnie nie najlepszy
       pomysł w tym przypadku), możesz zapisać to inaczej:

           *$nazwa = sub ($) { "<FONT COLOR='$nazwa'>$_[0]</FONT>" };

       Jednakże, ponieważ sprawdzanie protypów odbywa się podczas kompilacji,
       powyższe przypisanie zostanie wykonane za późno, by było przydatne.
       Mógłbyś to obejść przez włożenie całej pętli przypisań do wnętrza bloku
       BEGINu, wymuszając wykonanie go w czasie kompilacji.

       Dostęp do zmiennych leksykalnych zmieniających typ -- jak te w pętli
       for powyższego przykładu-- działa wyłącznie z zamknięciami, a nie z
       procedurami w ogóle. Zatem w przypadku ogólnym, procedury nazwane nie
       zagnieżdżają się prawidłowo, choć robią to procedury anonimowe.  Jeśli
       nawykłeś do używania zagnieżdżonych procedur z własnymi prywatnymi
       zmiennymi w innych językach programowania, to w Perlu będziesz musiał
       nad trochę popracować. Intuicyjna metoda kodowania tego typu rzeczy
       spowoduje tajemnicze ostrzeżenia ``will not stay shared'' (nie
       pozostanie wspólne).  To, na przykład, nie zadziała:

           sub zewn {
               my $x = $_[0] + 35;
               sub wewn { return $x * 19 }   # ŹLE
               return $x + wewn();
           }

       Obejście jest następujące:

           sub zewn {
               my $x = $_[0] + 35;
               local *wewn = sub { return $x * 19 };
               return $x + wewn();
           }

       Teraz wewn() może być wywołana tylko z wnętrza zewn(), z powodu
       tymczasowego przypisania zamknięcia (procedury anonimowej). Ale kiedy
       jest wywoływana, to ma zwykły dostęp do zmiennej leksykalnej $x z
       zakresu procedury zewn().

       Ma to interesujący skutek tworzenia funkcji lokalnych względem innych
       funkcji, co normalnie nie jest obsługiwane w Perlu.

OSTRZEŻENIE

       Nie możesz (w użyteczny sposób) posłużyć się odwołaniem jako kluczem
       hasza.  Zostanie ono zamienione na łańcuch:

           $x{ \$a } = $a;

       Jeśli spróbujesz zdereferencjonować klucz, nie otrzymasz odwołania
       stałego a łańcuch i nie uzyskasz tego, co próbowałeś. W zamian można
       napisać coś podobnego do:

           $r = \@a;
           $x{ $r } = $r;

       a następnie użyć values(), co zwróci rzeczywiste odwołania, zamiast
       użycia keys(), gdyż klucze odwołaniami nie będą.

       Standardowy moduł Tie::RefHash umożliwia wygodny sposób obejścia tego
       problemu.

ZOBACZ TAKŻE

       Poza oczywistą dokumentacją, pouczająca może być analiza kodu
       źródłowego.  Kilka raczej patologicznych przykładów użycia odwołań
       znajdziesz w teście regresji t/op/ref.t w katalogu źródeł Perla.

       Zobacz również podręczniki perldsc(1) i perllol(1), opisujące
       posługiwanie się odwołaniami do tworzenia złożonych struktur danych,
       oraz perltoot(1), perlobj(1) i perlbot(1) opisujące ich użycie do
       tworzenia obiektów.