perlsyn

Autres langues

Langue: pl

Autres versions - même langue

Version: perl 5.005, patch 02 (openSuse - 09/10/07)

Section: 1 (Commandes utilisateur)

NAZWA

perlsyn - Sk³adnia perla

OPIS

Skrypt perla sk³ada siê z sekwencji deklaracji i instrukcji. Jedynymi rzeczami, które musz± byæ zadeklarowane w perlu, to formatki raportowe i procedury. Wiêcej informacji o tych deklaracji znajdziesz w sekcjach poni¿ej. Wszystkie niezainicjalizowane, stworzone przez u¿ytkownika obiekty, uznawane s± za posiadaj±ce pocz±tkow± warto¶æ null lub 0, dopóki nie zostan± zdefiniowane w jakiej¶ jawnej operacji, jak np. przypisanie. (Choæ je¶li chcesz, mo¿esz dostawaæ ostrze¿enia o u¿ywaniu warto¶ci niezdefiniowanych.) Sekwencja instrukcji jest wykonywana tylko jednokrotnie, w przeciwieñstwie do skryptów sed(1) czy awk(1), gdzie sekwencja taka jest wykonywana dla ka¿dej linii wej¶ciowej. Oznacza to, ¿e musisz jawnie przetwarzaæ w pêtli linie swojego pliku wej¶ciowego (lub plików), oznacza to te¿, ¿e masz du¿o wiêksz± kontrolê nad tym, którymi plikami i liniami siê zajmujesz. (W³a¶ciwie to k³amiê---mo¿na zrobiæ niejawn± pêtlê za pomoc± prze³±cznika -n lub -p. Nie jest to po prostu domy¶lne i zarazem obowi±zkowe jak w sed(1) czy awk(1).)

Deklaracje

Perl jest w ogólno¶ci jêzykiem wolnej postaci (free-form). (Jedynym wyj±tkiem s± deklaracjê formatek--z oczywistych przyczyn.) Komentarze s± rozpoczynane znakiem ``#'' i ci±gn± siê do koñca linii. Je¶li spróbujesz u¿yæ komentarzy /* */ w stylu C, to zostan± one zinterpretowane albo jako dzielenie, albo jako porównywanie wzorca. Z kolei komentarz // z C++ wygl±da dok³adnie jak puste wyra¿enie regularne. Nie kombinuj wiêc z tymi konstrukcjami.

Deklaracja mo¿e byæ wstawiona gdziekolwiek, gdzie mo¿na wstawiæ instrukcjê, lecz nie ma wp³ywu na wykonywanie podstawowej sekwencji instrukcji---deklaracje maj± znaczenie tylko podczas kompilacji. Zazwyczaj wszystkie deklaracje wstawiane s± na pocz±tku lub na koñcu skryptu. Je¶li jednak u¿ywasz zmiennych prywatnych zawê¿onych leksykalnie, utworzonych przez my(), bêdziesz musia³ siê upewniæ, czy twoja definicja formatki lub procedury, u¿ywaj±cej tych deklaracji le¿y wewn±trz tego samego zakresu.

Deklarowanie procedury zezwala na u¿ywanie jej nazwy tak, jakby by³a operatorem listowym, licz±c od tego miejsca, a¿ do koñca programu. Mo¿esz zadeklarowaæ procedurê bez jej definiowania, pisz±c sub name, wiêc:


    sub myname;

    $me = myname $0             or die "can't get myname";





Zauwa¿, ¿e dzia³a to jak operator listowy, a nie jak jednoargumentowy; uwa¿aj wiêc i u¿ywaj or zamiast ||. Jednak je¶li zadeklarowa³by¶ procedurê jako sub myname ($), to myname funkcjonowa³oby jak operator jednoargumentowy, wiêc dzia³a³yby zarówno or jak i ||.

Deklaracje procedur mog± byæ równie¿ ³adowane instrukcj± require, lub jednocze¶nie ³adowane jak i importowane do przestrzeni nazw dziêki instrukcji use. Dla szczegó³ów polecam podrêcznik perlmod(1).

Sekwencja instrukcji mo¿e zawieraæ deklaracje zmiennych zawê¿onych leksykalnie, lecz poza deklarowaniem nazwy zmiennej, deklaracja dzia³a jak zwyk³a instrukcja i jest wykonywana w sekwencji instrukcji jak zwyczajna instrukcja. Znaczy to, ¿e ma ona zarówno skutki podczas kompilacji, jak w czasie dzia³ania.

Instrukcje proste

Jedynym rodzajem instrukcji prostej jest wyra¿enie, analizowane dla swoich efektów ubocznych. Ka¿da instrukcja prosta musi siê koñczyæ ¶rednikiem, chyba ¿e jest ostatni± instrukcj± bloku, wtedy ¶rednik nie jest obowi±zuj±cy. (Jednak wci±¿ jest zalecany je¶li blok zajmuje wiêcej ni¿ jedn± liniê, gdy¿ mo¿liwe ¿e dodasz jeszcze kolejne linie.) Zauwa¿, ¿e istniej± operatory takie, jak eval {} i do {}, które wygl±daj± jak instrukcje z³o¿one, lecz nimi nie s± i wymagaj± jawnego zakoñczenia je¶li s± u¿yte jako ostatni element instrukcji.

Za ka¿d± prost± instrukcj±, tu¿ przed ¶rednikiem (lub koñcem bloku) mo¿e znajdowaæ siê POJEDYNCZY modyfikator. Dopuszczalne modyfikatory to:


    if WYRA¯

    unless WYRA¯

    while WYRA¯

    until WYRA¯

    foreach WYRA¯





Modyfikatory if i unless maj± semantykê zgodn± z oczekiwaniami (je¿eli i chyba ¿e). Modyfikator foreach jest iteratorem: dla ka¿dej warto¶ci w WYRA¯ przypisuje jej nazwê zastêpcz± $_ i wykonuje instrukcjê. Modyfikatory while i until równie¿ maj± typow± semantykê pêtli while (warunek jest analizowany najpierw). Wyj±tkiem jest poprzedzenie tych modyfikatorów konstrukcj± do-BLOK - wówczas blok jest wykonywany raz przed sprawdzeniem warunku. Dziêki temu mo¿esz tworzyæ pêtle w rodzaju:

    do {

        $line = <STDIN>;

        ...

    } until $line  eq ".\n";





Zobacz opis do w podrêczniku perlfunc. Zauwa¿ te¿, ¿e opisane poni¿ej instrukcje kontroli pêtli NIE bêd± dzia³a³y w tej konstrukcji, gdy¿ modyfikatory nie pobieraj± etykiet pêtli. Przykro mi. Mo¿esz zawsze umie¶ciæ wewn±trz inny blok (dla WnextfR) lub te¿ umie¶ciæ swoj± instrukcjê wewn±trz bloku (dla last), aby zrobiæ co¶ takiego. W przypadku next po prostu podwój nawiasy:

   do {{

      next if $x == $y;

      # co¶ tu robi

   }} until $x++ > $z;





Dla next musisz siê bardziej rozpisaæ:

   LOOP: {

           do {

              last if $x = $y**2;

              # co¶ tu robi

           } while $x++ <= $z;

   }





Instrukcje z³o¿one

W perlu, sekwencja instrukcji definiuj±ca zakres nazywana jest blokiem. Czasami ograniczeniem bloku stanowi zawieraj±cy go plik (w wypadku wymaganego (required) pliku lub programu jako ca³o¶ci), a czasami zasiêg ³añcucha znakowego (w wypadku eval).

Lecz ogólnie, blok jest ograniczony nawiasami klamrowymi. Tak± konstrukcjê syntaktyczn± nazwiemy BLOKIEM.

Do kontroli przep³ywu mo¿na u¿ywaæ nastêpuj±cych instrukcji z³o¿onych:


    if (WYRA¯) BLOK

    if (WYRA¯) BLOK else BLOK

    if (WYRA¯) BLOK elsif (WYRA¯) BLOK ... else BLOK

    ETYKIETA while (WYRA¿) BLOK

    ETYKIETA while (WYRA¯) BLOK continue BLOK

    ETYKIETA for (WYRA¯; WYRA¯; WYRA¯) BLOK

    ETYKIETA foreach VAR (LISTA) BLOK

    ETYKIETA BLOK continue BLOK





Zauwa¿, ¿e w przeciwieñstwie do C i Pacala, s± one zdefiniowane w kategoriach BLOKÓW, a nie instrukcji. Znaczy to, ¿e nawiasy klamrowe s± niezbêdne--wisz±ce instrukcje nie s± dozwolone. Je¶li chcesz pisaæ warunki bez nawiasów, to s± na to inne sposoby. Nastêpuj±ce przyk³ady robi± wszystkie to samo:

    if (!open(FOO)) { die "Can't open $FOO: $!"; }

    die "Can't open $FOO: $!" unless open(FOO);

    open(FOO) or die "Can't open $FOO: $!";     # FOO lub giñ!

    open(FOO) ? 'hi mom' : die "Can't open $FOO: $!";

                        # to ostatnie trochê egzotyczne





Instrukcja if jest nieskomplikowana. Poniewa¿ BLOKI s± zawsze ograniczone nawiasami klamrowymi, nigdy nie ma niejednoznaczno¶ci co do tego, do którego if przynale¿y dany else. Je¶li zamiast if u¿ywasz unless, sens testu jest odwrócony.

Instrukcja while wykonuje swój blok tak d³ugo, jak wyra¿enie jest prawdziwe (jego warto¶ci± nie jest ³añcuch pusty, 0 czy ``0"). ETYKIETA jest opcjonalna, a je¶li jest obecna, sk³ada siê z identyfikatora, za którym nastêpuje dwukropek. ETYKIETA identyfikuje pêtlê dla instrukcji kontroli pêtli, czyli next, last i redo. Je¶li pominiêto ETYKIETÊ, instrukcje kontroli pêtli odnosz± siê do najbardziej wewnêtrznej otaczaj±cej pêtli. Mo¿e to wymagaæ dynamicznego przegl±dania wstecz stosu wywo³añ w czasie wykonania, aby znale¼æ odpowiedni± ETYKIETÊ. Takie desperackie zachowania daj± zwykle ostrze¿enia przy w³±czonej fladze -w.

Je¶li istnieje BLOK continue, to jest on zawsze wykonywany tu¿ przed kolejn± analiz± warunku, podobnie jak trzeci element pêtli for w C. Mo¿na tego u¿ywaæ do zwiêkszania zmiennej steruj±cej pêtli, nawet gdy pêtla jest w³a¶nie kontynuowana instrukcj± next (która jest z kolei podobna do instrukcji continue z C).

Kontrola pêtli

Polecenie next jest podobne do instrukcji continue z C; rozpoczyna now± iteracjê pêtli:

    LINE: while (<STDIN>) {

        next LINE if /^#/;      # wykasuj komentarze

        ...

    }





Polecenie last jest podobne do instrukcji break z C (u¿ywanej w pêtlach); natychmiastowo opuszcza pêtlê. Blok continue nie jest wykonywany:

    LINE: while (<STDIN>) {

        last LINE if /^$/;      # zakoñcz po obs³u¿eniu nag³ówka

        ...

    }





Polecenie redo restartuje pêtlê bez ponownego analizowania warunku. Blok continue nie jest wykonywany. Polecenie to jest zazwyczaj u¿ywane w programach, które chc± siê ok³amywaæ co do tego, co w³a¶nie pobra³y z wej¶cia.

Na przyk³ad, podczas przetwarzania pliku takiego, jak /etc/termcap. Je¶li twoje wiersze wej¶ciowe mog± siê koñczyæ lewymi uko¶nikami, wskazuj±cymi kontynuacjê, mo¿esz chcieæ z wyprzedzeniem pobraæ nastêpny rekord.


    while (<>) {

        chomp;

        if (s/\\$//) {

            $_ .= <>;

            redo unless eof();

        }

        # teraz przetwórz $_

    }





co w perlu jest skrótem dla wersji napisanej bardziej dos³ownie:

    LINE: while (defined($line = <ARGV>)) {

        chomp($line);

        if ($line =~ s/\\$//) {

            $line .= <ARGV>;

            redo LINE unless eof(); # nie eof(ARGV)!

        }

        # teraz przetwórz $line

    }





A tu mamy prosty striptizer komentarzy Pascalowych (uwaga: zak³ada brak { lub } w ³añcuchach).

    LINE: while (<STDIN>) {

        while (s|({.*}.*){.*}|$1 |) {}

        s|{.*}| |;

        if (s|{.*| |) {

            $front = $_;

            while (<STDIN>) {

                if (/}/) {      # koniec komentarza?

                    s|^|$front{|;

                    redo LINE;

                }

            }

        }

        print;

    }





Zauwa¿, ¿e je¶li w powy¿szym kodzie istnia³by blok continue, zosta³ by on wywo³any nawet dla usuniêtych wierszy. Blok ten jest czêsto u¿ywany do resetowania liczników wierszy czy jednokrotnych dopasowañ ?wzorców?.

    # zainspirowane przez :1,$g/fred/s//WILMA/

    while (<>) {

       ?(fred)?     && s//WILMA $1 WILMA/;

       ?(barney)?   && s//BETTY $1 BETTY/;

       ?(homer)?    && s//MARGE $1 MARGE/;

    } continue {

       print "$ARGV $.: $_";

       close ARGV   if eof();    # reset $. (nr wiersza)

       reset        if eof();    # reset ?wzorca?

    }





Je¶li s³owo while jest zamieniane s³owem until, to sens testu jest odwrócony, lecz warunek jest wci±¿ testowany w pierwszej iteracji.

Instrukcje steruj±ce pêtli nie wspó³pracuj± z if ani unless, gdy¿ nie s± one pêtlami. Mo¿esz jednak podwoiæ nawiasy by je nimi uczyniæ.


    if (/wzorzec/) {{

       next if /fred/;

       next if /barney/;

       # co¶ tu robi

    }}

Postaæ while/if BLOCK BLOCK, która by³a dostêpna w Perl 4 nie jest

ju¿ prawid³owa. Zmieñ wszystkie wyst±pienia

if BLOCK na if (do BLOCK).

 

Pêtle for

Perlowa pêtla for w stylu C, dzia³a dok³adnie jak odpowiadaj±ca jej pêtla while, co znaczy, ¿e to:

    for ($i = 1; $i < 10; $i++) {

        ...

    }





jest tym samym, co to:

    $i = 1;

    while ($i < 10) {

        ...

    } continue {

        $i++;

    }





(Jest jedna drobna ró¿nica: pierwsza postaæ wymusza zawê¿enie leksykalne dla zmiennych zadeklarowanych przez my w wyra¿eniu inicjalizacji.)

Poza zwyk³ymi pêtlami po indeksach tablic, for daje wiele innych zastosowañ. Oto przyk³ad, zapobiegaj±cy problemowi, który napotyka siê testuj±c jawnie EOF na interaktywnym deskryptorze pliku, co powoduje, ¿e program wygl±da jakby siê zawiesi³.


    $on_a_tty = -t STDIN && -t STDOUT;

    sub prompt { print "yes? " if $on_a_tty }

    for ( prompt(); <STDIN>; prompt() ) {

        # zrób co¶

    }





Pêtle foreach

Pêtla foreach iteruje poprzez normaln± warto¶æ listow± i przypisuje zmiennej VAR warto¶æ ka¿dego kolejnego elementu listy. Je¶li zmienna jest poprzedzona s³owem kluczowym my, to jest ona leksykalnie zawê¿ona i widzialna tylko wewn±trz pêtli. W przeciwnym wypadku, zmienna jest niejawnie lokalna w pêtli i, po wyj¶ciu z niej, odzyskuje pierwotn± warto¶æ. Je¶li zmienna by³a poprzednio zadeklarowana przez my, to pêtla u¿ywa tej zmiennej, zamiast zmiennej globalnej, lecz wci±¿ jest ona lokalna w obrêbie pêtli. (Zauwa¿, ¿e zmienne o zasiêgu leksykalnym mog± byæ przyczyn± k³opotów, je¶li wewn±trz pêtli masz odwo³uj±ce siê do nich procedury lub deklaracje formatów.)

S³owo kluczowe foreach jest w rzeczywisto¶ci synonimem s³owa for, wiêc foreach mo¿esz u¿ywaæ dla czytelno¶ci, a for dla skrócenia. (Albo te¿ pow³oka Bourne'a jest Ci milsza ni¿ csh, wiêc pisanie for jest naturalniejsze.) Je¶li VAR jest pominiête, na kolejne warto¶ci ustawiane bêdzie $_. Je¶li dowolny element LISTY jest lwarto¶ci±, to mo¿esz ³atwo modyfikowaæ jego warto¶æ, modyfikuj±c VAR wewn±trz pêtli. Jest tak dlatego, ¿e zmienna indeksu pêtli foreach jest niejawnym synonimem ka¿dego iterowanego elementu. W szczególno¶ci mo¿liwa jest zmiana tym sposobem warto¶ci elementów tablicy LISTA (ale nie wyra¿enia zwracaj±cego LISTÊ).

Je¶li dowolna czê¶æ LISTY jest tablic±, to foreach bardzo siê zmiesza, je¶li wewn±trz pêtli dodasz lub usuniesz elementy, na przyk³ad przy pomocy splice. Nie rób wiêc tego.

foreach prawdopodobnie nie zrobi tego, czego oczekujesz, je¶li VAR jest zmienn± specjaln±. Tego te¿ nie rób.

Przyk³ady:


    for (@ary) { s/foo/bar/ }






    foreach my $elem (@elements) {

        $elem *= 2;

    }






    for $count (10,9,8,7,6,5,4,3,2,1,'BOOM') {

        print $count, "\n"; sleep(1);

    }






    for (1..15) { print "Merry Christmas\n"; }






    foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) {

        print "Item: $item\n";

    }





Oto, jak programista C móg³by zakodowaæ szczególny algorytm w perlu:

    for (my $i = 0; $i < @ary1; $i++) {

        for (my $j = 0; $j < @ary2; $j++) {

            if ($ary1[$i] > $ary2[$j]) {

                last; # nie mogê wyj¶æ do zewnêtrznej :-(

            }

            $ary1[$i] += $ary2[$j];

        }

        # tu zabiera mnie last

    }





Podczas gdy programista perla móg³by zrobiæ to wygodniej:

    OUTER: foreach my $wid (@ary1) {

    INNER:   foreach my $jet (@ary2) {

                next OUTER if $wid > $jet;

                $wid += $jet;

             }

          }





Widzisz jakie to proste? Czystsze, bezpieczniejsze i szybsze. Jest czystsze, bo mniej tu zamieszania. Jest bezpieczniejsze, bo je¶li miêdzy wewnêtrzn±, a zewnêtrzn± pêtlê zostanie pó¼niej dodany kod, to nie bêdzie on przypadkiem wykonywany. next jawnie iteruje inn± pêtlê zamiast przerywania wewnêtrznej. Jest to szybsze, gdy¿ perl wywo³uje instrukcje foreach szybciej ni¿ równowa¿nik z pêtl± for.

Podstawowe instrukcje BLOKOWE i switch

BLOK (z etykiet± lub bez) jest równowa¿ny pêtli, która jest wykonywana jeden raz. Tak wiêc mo¿esz wewn±trz u¿ywaæ instrukcji kontroli pêtli by wyj¶æ z bloku lub ponowiæ jego wykonanie. (Zauwa¿, ¿e nie jest to prawd± wewn±trz eval{}, sub{} czy, przeciwnie do rozpowszchnionych przekonañ, bloków do{}, które nie zaliczaj± siê do pêtli.) Blok continue jest opcjonalny.

Konstrukcja BLOKU jest szczególnie wygodna do tworzenia struktur wyboru (case).


    SWITCH: {

        if (/^abc/) { $abc = 1; last SWITCH; }

        if (/^def/) { $def = 1; last SWITCH; }

        if (/^xyz/) { $xyz = 1; last SWITCH; }

        $nothing = 1;

    }





W perlu nie ma oficjalnej instrukcji switch, gdy¿ istnieje ju¿ kilka sposobów na wykonanie jej równowa¿nika. Oprócz, móg³by¶ napisaæ

    SWITCH: {

        $abc = 1, last SWITCH  if /^abc/;

        $def = 1, last SWITCH  if /^def/;

        $xyz = 1, last SWITCH  if /^xyz/;

        $nothing = 1;

    }





(W rzeczywisto¶ci nie jest to tak dziwne jak wygl±da. Musisz sobie u¶wiadomiæ, ¿e mo¿esz korzystaæ z ``operatorów'' kontroli pêtli wewn±trz wyra¿eñ. Jest to zwyczajny operator przecinka z C.)

lub


    SWITCH: {

        /^abc/ && do { $abc = 1; last SWITCH; };

        /^def/ && do { $def = 1; last SWITCH; };

        /^xyz/ && do { $xyz = 1; last SWITCH; };

        $nothing = 1;

    }





lub sformatowane w taki sposób, ¿e wygl±da bardziej na ``poprawn±'' instrukcjê switch:

    SWITCH: {

        /^abc/      && do {

                            $abc = 1;

                            last SWITCH;

                       };






        /^def/      && do {

                            $def = 1;

                            last SWITCH;

                       };






        /^xyz/      && do {

                            $xyz = 1;

                            last SWITCH;

                        };

        $nothing = 1;

    }





lub

    SWITCH: {

        /^abc/ and $abc = 1, last SWITCH;

        /^def/ and $def = 1, last SWITCH;

        /^xyz/ and $xyz = 1, last SWITCH;

        $nothing = 1;

    }





lub nawet straszliwe

    if (/^abc/)

        { $abc = 1 }

    elsif (/^def/)

        { $def = 1 }

    elsif (/^xyz/)

        { $xyz = 1 }

    else

        { $nothing = 1 }





Popularnym idiomem instrukcji switch jest wykorzystanie tworzonego przez foreach synonimu. Uzyskane tymczasowe przypisanie do zmiennej $_ umo¿liwia wygodne dopasowywanie:

    SWITCH: for ($where) {

                /In Card Names/     && do { push @flags, '-e'; last; };

                /Anywhere/          && do { push @flags, '-h'; last; };

                /In Rulings/        && do {                    last; };

                die "unknown value for form variable where: `$where'";

            }





Innym interesuj±cym podej¶ciem do instrukcji switch jest rozplanowanie bloku do tak, by zwraca³ w³a¶ciw± warto¶æ:

    $amode = do {

        if     ($flag & O_RDONLY) { "r" }

        elsif  ($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" }

        elsif  ($flag & O_RDWR)   {

            if ($flag & O_CREAT)  { "w+" }

            else                  { ($flag & O_APPEND) ? "a+" : "r+" }

        }

    };





lub te¿

        print do {

            ($flags & O_WRONLY) ? "write-only"          :

            ($flags & O_RDWR)   ? "read-write"          :

                                  "read-only";

        };





albo, je¶li jeste¶ pewien, ¿e wszystkie klauzule && s± prawdziwe, mo¿esz pos³u¿yæ siê czym¶ podobnym, co "prze³±cza" w zale¿no¶ci od warto¶ci zmiennej ¶rodowiska HTTP_USER_AGENT.

    #!/usr/bin/perl 

    # dobierz plik ze stron± ¿argonu wed³ug przegl±darki

    $dir = 'http://www.wins.uva.nl/~mes/jargon';

    for ($ENV{HTTP_USER_AGENT}) { 

        $page  =    /Mac/            && 'm/Macintrash.html'

                 || /Win(dows )?NT/  && 'e/evilandrude.html'

                 || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html'

                 || /Linux/          && 'l/Linux.html'

                 || /HP-UX/          && 'h/HP-SUX.html'

                 || /SunOS/          && 's/ScumOS.html'

                 ||                     'a/AppendixB.html';

    }

    print "Location: $dir/$page\015\012\015\012";





Ten rodzaj instrukcji switch dzia³a tylko, gdy wiesz, ¿e klauzule && bêd± prawdziwe. Je¶li nie, to powinien byæ u¿yty poprzedni przyk³ad z ?:.

Mo¿esz tak¿e rozwa¿yæ napisanie hasza (tablicy asocjacyjnej) zamiast syntezowania instrukcji switch.

Goto

Perl obs³uguje instrukcjê goto. ETYKIETA pêtli nie jest w rzeczywisto¶ci prawid³owym celem goto; jest tylko nazw± pêtli. Istniej± trzy postacie: goto-ETYKIETA, goto-WYRA¯ i goto-&NAZWA.

Postaæ goto-ETYKIETA szuka instrukcji oznaczonej ETYKIET¡ i kontynuuje wykonywanie w tym miejscu. Nie mo¿e byæ u¿ywana do wchodzenia do wnêtrza konstrukcji, które wymagaj± inicjalizacji, takich jak procedury lub pêtle foreach. Nie mo¿e te¿ byæ u¿ywana do wchodzenia do konstrukcji, które s± w jaki¶ sposób optymalizowane. Mo¿e byæ u¿ywane do wchodzenia prawie we wszystkie inne miejsca w zakresie dynamicznym, ³±cznie z wychodzeniem z procedur, lecz zwykle lepiej jest u¿yæ konstrukcji takiej jak last lub die. Autor Perla nigdy nie czu³ potrzeby u¿ywania tej postaci goto (w Perlu---C to inna sprawa).

Postaæ goto-WYRA¯ oczekuje nazwy etykiety, której zakres zostanie rozwi±zany dynamicznie. Umo¿liwia to stosowanie wyliczanych goto jak w FORTRANie, lecz nie jest zbyt zalecane je¶li optymalizujesz z uwagi na konserwacjê programu:


    goto ("FOO", "BAR", "GLARCH")[$i];





Postaæ goto-&NAZWA jest bardzo magiczna i podstawia wywo³anie do nazwanej procedury za bie¿±c± procedurê. Jest to u¿ywane przez procedury AUTOLOAD(), które chc± ³adowaæ inne procedury, a potem udawaæ, ¿e inna procedura zosta³a wywo³ana jako pierwsza (poza tym, ¿e wszelkie modyfikacje @_ w bie¿±cej procedurrze s± przenoszone do tej innej procedury.) Po takim goto, nawet caller() nie bêdzie w stanie powiedzieæ, ¿e ta procedura zosta³a wywo³ana pierwsza.

W wiêkszo¶ci tego typu przypadków, zazwyczaj du¿o, du¿o lepszym pomys³em jest u¿ywanie strukturalnych mechanizmów kontroli przep³ywu next, last lub redo, zamiast zwracaæ siê ku goto. Dla niektórych zastosowañ, para eval{} i die(), s³u¿±ca do przetwarzania wyj±tków mo¿e byæ te¿ rozs±dnym wyj¶ciem.

POD: Osadzona dokumentacja

Perl posiada mechanizm ³±czenia dokumentacji z kodem ¼ród³owym. Podczas oczekiwania pocz±tku nowej instrukcji, je¶li kompilator natrafi na liniê, rozpoczynaj±c± siê od znaku równo¶ci i s³owa, jak

    =head1 Here There Be Pods!





To ten tekst, oraz reszta napisów, a¿ do linii, rozpoczynaj±cej siê od =cut w³±cznie zostan± zignorowane. Format tekstu wtr±conego jest opisany w podrêczniku perlpod(1).

Umo¿liwia ci to ³±czenie kodu ¼ród³owego i dokumentacji, jak w


    =item snazzle($)






    Funkcja snazzle() bêdzie zachowywaæ siê w najbardziej spektakularny

    sposób, jaki mo¿esz sobie wyobraziæ, prze¶cigaj±c nawet cyber

    pirotechnikê.






    =cut powrót do kompilatora, fora z tego pod-fora!






    sub snazzle($) {

        my $thingie = shift;

        .........

    }





Zauwa¿, ¿e translatory pod powinny patrzeæ tylko na akapity, rozpoczynaj±ce siê od dyrektywy pod (u³atwia to przetwarzanie), podczas gdy kompilator wie, ¿e ma szukaæ sekwencji specjalnych pod nawet w ¶rodku akapitu. Znaczy to, ¿e nastêpuj±cy tajny tekst bêdzie ignorowany zarówno przez kompilator, jak i przez translatory.

    $a=3;

    =tajne rzeczy

     warn "Ani POD ani KOD!?"

    =cut powrot

    print "got $a\n";





Prawdopodobnie nie powiniene¶ opieraæ siê na warn(), "wypodowanym" na zawsze. Nie wszystkie translatory zachowuj± siê w tym momencie dobrze i byæ mo¿e kompilator stanie siê wybredniejszy.

Dyrektyw pod mo¿na te¿ u¿ywaæ do szybkiego wykomentowania sekcji kodu.

Plain Old Comments (Nie!)

Podobnie jak preprocesor C, perl mo¿e przetwarzaæ dyrektywy liniowe. Przy ich u¿yciu, mo¿na kontrolowaæ perlowe pojêcie nazw plików i numerów linii w komunikatach o b³êdach/ostrze¿eniach (szczególnie dla ³añcuchów, które s± przetwarzane z eval()). Sk³adnia tego mechanizmu jest taka sama dla jak dla wiêkszo¶ci preprocesorów C: dopasowuje wyra¿enie regularne /^#\s*line\s+(\d+)\s*(?:\s"([^"]*)")?/ do $1, bêd±cego numerem linii i $2, bêd±cego opcjonaln± nazw± pliku (podan± w cudzys³owach).

Oto niektóre przyk³ady, które mo¿esz sprawdziæ w swojej pow³oce:


    % perl

    # line 200 "bzzzt"

    # znak `#' w poprzedniej linii musi byæ pierwszym znakiem linii

    die 'foo';

    __END__

    foo at bzzzt line 201.






    % perl

    # line 200 "bzzzt"

    eval qq[\n#line 2001 ""\ndie 'foo']; print $@;

    __END__

    foo at - line 2001.






    % perl

    eval qq[\n#line 200 "foo bar"\ndie 'foo']; print $@;

    __END__

    foo at foo bar line 200.






    % perl

    # line 345 "goop"

    eval "\n#line " . __LINE__ . ' "' . __FILE__ ."\"\ndie 'foo'";

    print $@;

    __END__

    foo at goop line 345.