Provided by: manpages-pl_0.7-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

        Uwaga! To tłumaczenie może być nieaktualne!

       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. POMIĘDZY 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.

INFORMACJE O TŁUMACZENIU

       Powyższe tłumaczenie pochodzi z nieistniejącego już Projektu Tłumaczenia Manuali i może
       nie być aktualne. W razie zauważenia różnic między powyższym opisem a rzeczywistym
       zachowaniem opisywanego programu lub funkcji, prosimy o zapoznanie się z oryginalną
       (angielską) wersją strony podręcznika za pomocą polecenia:

              man --locale=C 1 perlref

       Prosimy o pomoc w aktualizacji stron man - więcej informacji można znaleźć pod adresem
       http://sourceforge.net/projects/manpages-pl/.