Provided by: manpages-pl_0.5-1_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/.

3rd Berkeley Distribution                     perl 5.005, patch 03                                    PERLREF(1)