Vladimir Maslov. Vvedenie v Perl --------------------------------------------------------------- © Copyright (C) Maslov Vladimir Viktorovich Vse zamechaniya i predlozheniya napravlyajte po adresu: maslov@klgtts.kaluga.su ¡ mailto:maslov@klgtts.kaluga.su maslov@news.kaluga.rosmail.com ¡ mailto:maslov@news.kaluga.rosmail.com --------------------------------------------------------------- Vse primery v knige provereny dlya Perl versii 5.003 operacionnoj sistemy Unix FreeBSD 2.1.0. =============================================================== Soderzhanie  * Annotaciya *  V knige privodyatsya nachal'nye svedeniya po novomu yazyku programmirovaniya Perl. Dannyj yazyk poluchil shirokoe rasprostranenie v svyazi s razvitiem komp'yuternoj seti Internet. Vse primery v knige provereny dlya Perl versii 5.003 operacionnoj sistemy Unix FreeBSD 2.1.0. Dlya programmistov, sistemnyh administratorov i pol'zovatelej komp'yuterov. (C) Maslov Vladimir Viktorovich.  * Ot prostogo k slozhnomu *  Prezhde chem pristupit' k posledovatel'nomu oznakomleniyu s ne znakomym dlya vas yazykom, dolzhen ogovorit'sya i skazat', chto vse primery da i sam yazyk opisaniyu kotorogo posvyashchena eta kniga eto Perl versii 5.003 dlya operacionnoj sistemy FreeBSD versii 2.01. Sushchestvuyut realizacii etogo yazyka dlya operacionnyh sistem OS/2 , MS-DOS i Windows NT no oni nemnogo otstayut po vozmozhnostyam ot originala, rozhdennogo v nedrah YUniksa. Primer 1 Vvedite v fajl test1.pl sleduyushchie stroki: #!/usr/local/bin/perl # Soderzhimoe fajla test1.pl print "Nashe Vam s kistochkoj!\n"; A teper' podrobno razberem kazhduyu stroku. #!/usr/local/bin/perl Dannaya stroka dolzhna byt' pervoj v lyuboj Pel-programme. Ona ukazyvanet sistemnomu interpretatoru chto dannyj fajl - eto Pel-programma. # Soderzhimoe fajla test1.pl |ta stroka nazyvaetsya kommentariem. Ona vsegda nachinaetsya simvolom '#' i zakanchivaetsya takim ob®yasneniem chto kak govoril velikij Hodzha Nasreddin "eto tonkij filosovskij vopros", a govorya prostym yazykom zdes' mozhno pisat' vse chto ugodno. Dazhe pozhelanie rukovodstvu. Uzh zdes' ono tochno do nego ne dojdet. print "Nashe Vam s kistochkoj!\n"; Samaya poslednyaya nu i konechno glavnaya. Ona prosto vyvodit na ekran nadpis' "Nashe Vam s kistochkoj!". Zdes' slovo print - eto komanda "vyvesti". Vse chto v kavychkah - eto simvoly, \n - perevod stroki i ';' - priznak konca komandy. On obyazatelen. V odnoj stroke mozhet byt' neskol'ko komand i vse oni dolzhny zavershat'sya simvolom ';'. Posle nego mozhet byt' simvol '#' - eto znachit ostatok stroki schitaetsya kommentariem. Nad etoj strokoj avtoru prishlos' bol'she vsego polomat' golovu tak kak v nee postoyanno lezli kakie to strannye "hello", "hello all", "Postroemsya i spasemsya", "Stroj nashe spasenie" i t.d i t.p. Esli vy nikogda ne rabotali s Pel, to b®yus' na spor v 10$, chto dannaya programma srazu u vas ne zarabotaet! Ne potomu chto ona ne verna, a potomu chto "Nel'zya ob®yat' neob®yatnoe". Srazu, potom mozhno, da i to chastyami. Snachalo sdelajte vash fajl test1.pl ispolnyaemym. Dlya etogo vvedite komandu: chmod +x test1.pl Zatem prover'te gde u vas Pel. Dlya etogo vvedite: which perl Sistema vam vydast chto to vrode: /usr/bin/perl Esli: perl: Command not found. To togda zakrojte knizhku i lozhites' spat'. U vas prosto net Pel ili on ne ustanovlen. A mne ostaetsya poslat' vas k sistemnomu administratoru ili k man (dlya perevodchikov- man sokrashchenie ot manual a ne to chto vy podumali). Teper' prover'te chto by stroka 01 soderzhala to chto vydala komanda which. Esli sovpalo to vvedite: test1.pl i b®s' na 50$ chto i teper' programma ne zarabotaet, tak kak pravil'nej vvesti: ./test1.pl Esli ya proigral, to ne radujtes'. Da zhe esli vam udalos' zapustit' programmu kak test1.pl eto znachit, chto u vas budut nepriyatnosti v budushchem. Primer 2 Dannaya programma vyvodit na ekran vse vashi sekrety. A imenno fajl /etc/passwd. #!/usr/local/bin/perl open(PASS, "</etc/passwd") || die "Fajl ne najden!"; while(<PASS>) { print; } close(PASS); Poyasneniya: open(PASS, "</etc/passwd") || die "Fajl ne najden!"; "Otkryt'" fajl t.e. sozdat' ukazatel' fajla PASS i v sluchae oshibki vydat' "Fajl ne najden!" i zakonchit' programmu. while(<PASS>) CHitat' po odnoj stroke fajla v peremennuyu po umolchaniyu $_. { Otkryt' blok operatorov. print; Vyvesti na ekran peremennuyu po umolchaniyu $_ } Konec bloka. close(PASS); Zakryt' fajl. |togo mozhno i ne delat' tak-kak fajl avtomaticheski zakroetsya posle okonchaniya programmy. Rezul'tat raboty etoj programmy tot zhe chto i komandy cat /etc/passwd. Po ekranu probezhali neponyatnye stroki no zato teper' pered vami otkryty gorizonty Pel programmirovaniya! Vse posleduyushchie primery budut razvitiem etoj programmy i ona prevratitsya iz gadkogo utenka v prekrasnogo lebedya (ne generala). Primer 3 Razdeleneie polej. #!/usr/local/bin/perl open(PASS, "</etc/passwd") || die "Fajl ne najden!"; while(<PASS>) { ($login, $pass, $uid, $gid, $name, $home_dir, $shell) = split(':'); print "$login \t $name\n"; } close(PASS); Poyasnenie: ($login, $pass, $uid, $gid, $name, $home_dir, $shell) = split(':'); Prisvoit' ukazannym peremennym polya vhodnoj stroki, schitaya razdelitelem simvol ':'. print "$login \t $name\n"; Vyvesti login - imya pol'zovatelya i ego opisanie. Polya razdeleny simvolom '\t' - tabulyacii. Primer 4 Vyvesti imena pol'zovatelej otsortirovannyh po gruppam. #!/usr/local/bin/perl open(PASS, "sort -n -t : +3 -4 +0 /etc/passwd|") || die "Fajl ne najden!"; while(<PASS>) { ($login, $pass, $uid, $gid, $name, $home_dir, $shell) = split(':'); print "$login \t $gid \t $name\n"; } close(PASS); Poesneniya: open(PASS, "sort -n -t : +3 -4 +0 /etc/passwd|") || die "Fajl ne najden!"; V dannoj stroke ves' fokus! Vhodnym fajlom dlya nashej programmy stal vyhod komandy sort kotoraya i otsortiruet vhodnye dannye. Formatirovannyj vyvod. Nu a teper' napechataem na ekrane vse nashi dannye v udobnoj forme. #!/usr/local/bin/perl open(PASS, "sort -n -t : +3 -4 +0 /etc/passwd|") || die "Fajl ne najden!"; while(<PASS>) { ($login, $pass, $uid, $gid, $name, $home_dir, $shell) = split(':'); write(); # Formatirovannyj yvod dannyh. } close(PASS); exit 0; # Zavershenie programmy ############ Opisanie formy vyvoda ################## format STDOUT = Pol'zovatel': ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $name ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $name ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $name ---------------------------------------------------------------------- Login:@<<<<<<<< Uid:@<<< Gid:@<<< Home dir:@<<<<<<<<<<<<<<<<<<<<< $login, $uid, $gid, $home_dir ---------------------------------------------------------------------- . # |to poslednyaya stroka programmy Fragment rezul'tata: Pol'zovatel': Kaluzhskij likero-vodochnyj zavod. Luchshie vodki i nastojki. Zvonit' tol'ko pered prazdnikom Kostrikovu Anatoliyu t. 2-23-06,,, ---------------------------------------------------------------------- Login:uucryst Uid:1055 Gid:66 Home dir:/var/spool/uucppublic/ ---------------------------------------------------------------------- Pol'zovatel': Torgovyj Dom Dilen,,, ---------------------------------------------------------------------- Login:uudilen Uid:1075 Gid:66 Home dir:/var/spool/uucppublic ---------------------------------------------------------------------- Esli vam interesno uznat' kak rabotaet eta programma, to perevernite stranicu i nachinite svoe puteshestvie v mire Pel. ZHelayu udachi!  * Zapusk interpretatora Pel *  Sintaksis: perl [klyuchi] fajl argumenty Pered startom Pel ishchet skript (programmu) v sleduyushchem poryadke: 1. V komandnoj stroke esli ukazan klyuch '-e' 2. Soderzhimoe fajla ukazannogo v komandnoj stroke. V pervoj stroke mozhno ukazyvat' #!/usr/bin/perl dlya "avtomaticheskogo" zapuska skripta. 3. Standartnyj vvod/vyvod esli ne ukazan fajl ili argumenty soderzhashchie imya fajla. Dlya peredachi argumentov skriptu iz standartnogo potoka imya fajla v komandnoj stroke oboznachaetsya simvolom '-'. V metodah 1 i 2 Pel skaniruet stroki nachinaya s pervoj esli ne ukazan klyuch '-x', v protivnom sluchae nachalom programmy schitaetsya stroka s simvolami '#!' v nachale i soderzhashchaya slovo 'perl'. Koncom programmy schitaetsya stroka '__END__'. V stroke s '#!' mozhno ukazyvat' i klyuchi. Naprimer '#!/bin/perl -d' dlya otladki programm. Posle "obnaruzheniya" skripta Pel kompiliruet ego celikom vo vnutrennee predstavlenie. Esli obnaruzhivayutsya oshibki to vypolnenie prekrashchaetsya. Esli oshibok net on vypolnyaetsya. Esli skript zakanchivaetsya bez komand exit() ili die() to po umolchaniyu vypolnyaetsya komanda exit(0) oboznachayushchaya normal'noe zavershenie programmy. Klyuchi: -Ocifry Kod simvola-razdelitelya zapisej. Po umolchaniyu \0. -a Vklyuchaet rezhim avtomaticheskogo razdeleniya (split) peremennoj $_ v massiv $F. Primenyaetsya s klyuchami -n i -p. -c Vypolnyaetsya sintaksicheskaya proverka skripta i vyhod bez zapuska. -d Zapusk v rezhime interaktivnoj otladki. -Dchislo ili Dspisok Ustanovit' flagi otladki Pel. Naprimer -d14 prosledit' kak Pel ispolnyaet vashu programmu. 1 p Sintaksicheskij razbor 2 s Sostoyanie steka 4 l Sostoyanie steka imen 8 t Trassirovka ispolneniya 16 o Sozdanie operatora uzla 32 c Strokovoe/chislovoe preobrazovanie 64 p Vyvod komandy preprocessora dlya -P 128 m Raspredelenie pamyati 256 f Obrabotka formata 512 r Sintaksicheskij razbor regulyarnyh vyrazhenij 1024 x Damp sintaksicheskogo dereva 2048 u Proverka zashchity 4096 L "Utechka" pamyati 8192 H Damp hesha 16384 X Raspredelenie scratchpad 32768 D Ochistka -e komanda Vypolnenie skripta iz odnoj stroki ukazannogo v komandnoj stroke. -F shablon Ukazyvaet shablon razdeleniya v rezhime raboty s klyuchom -a -irasshirenie Primenyaetsya dlya rezervnoj kopii fajla obrabatyvaemogo operatorom '<>'. Original hranitsya v fajle s tem zhe imenem chto i ishodnyj, no s ukazannym rasshireniem. Primer: perl -p -i.old -e "s/ryadovoj/efrejtor/" file - Pomenyat' vse slova "ryadovoj" na "efrejtor" v fajle file a original zapisat' v fajle file.old -Idirektoriya Direktoriya includ- fajlov dlya S preprocessora. Primenyaetsya s klyuchom -P po umolchaniyu eto /usr/include i /usr/lib/perl. -lchislo Avtomaticheskaya obrabotka simvola konca stroki. Rabotaet v dvuh sluchayah. 1. Otbrasyvaet poslednij simvol chitaemyh strok dlya rezhimov -n i -p 2. Prisvaivaet ukazannoe znachenie peremennoj $\. Takim obrazom k koncu kazhdoj stroki vyvodimoj operatorom print dobavlyaetsya etot simvol. -n Zaciklivaet skript i posledovatel'no obrabatyvaet fajly ukazannye v komandnoj stroke. Pozvolyaet sozdavat' komandy podobnye sed ili awk. Operatory BEGIN i END dayut vozmozhnost' delat' nachal'nye i konechnye ustanovki. Soderzhimoe fajlov ne vyvoditsya. -p To zhe chto i -n no pechataet obrabatyvaemye stroki fajlov. -P Predvaritel'naya obrabotko preprocessorom yazyka S. Bud'te vnimatel'ny i ne primenyajte v kommentariyah slova 'if', 'else' ili 'define' t.k. eto komandy S - preprocessora. -s Vklyuchenie rezhima obrabotki klyuchej komandnoj stroki zapuska skripta. Vse argumenty s simvolom '-' v nachale, schitayutsya klyuchom i peremennym s takim zhe imenem prisvaivaetsya znachenie true. -S Ispol'zovanie sistemnoj peremennoj PATH dlya poiska skripta. Dannyj klyuch primenyaetsya v sistemah ne vosprinimayushchih posledovatel'nost' "#!" v nachale skripta dlya ukazaniya interpretatora. -T Rezhim proverki "dyr" v zashchite. Obychno eto nuzhno dlya programm rabotayushchih v rezhime povyshennoj privelegii (setuid, setguid). ZHelatel'no dlya CGI skriptov. -u Prinuditel'nyj damp pamyati posle kompilyacii skripta. |tot damp mozhno potom ispol'zovat' dlya sozdaniya ispolnyaemogo fajla s pomoshch'yu programmy undump. -U Razreshenie vypolnyat' opasnye operacii. Naprimer steret' direktoriyu ili vypolnyat' yavno ne zakrytuyu programmu. -v Vyvod nomera versii Pel. -w Vyvod imen peremennyh ispol'zuemyh tol'ko odin raz, imen skalyarov ispol'zuemyh do ih opredeleniya, imen pereopredelyaemyh podprogramm, ssylok na neopredelennyj ukazateli fajlov, popytok zapisi v fajly otkrytyh tol'ko na "chtenie", upotreblenie ne koretnyh zapisej chisel, ispol'zovanie massivov kak skalyarov, rekursiya bolee 100 urovnej. -x direktoriya Rezhim zapuska skripta vstavlennogo v fajl soderzhashchij obychnyj tekst. Nachalom skripta schitaestsya stroka s simvolami '#!' v nachale i soderzhashchiya slovo perl. Koncom - stroka s '__END__' Ukazannaya direktoriya stanovitsya tekushchej v moment ispolneniya. Esli neobhodimo chitat' posleduyushchie stroki to eto luchshe delat' cherez ukazatel' fajla DATA.  * Sintaksis *  Pel programma (skript) sostoit iz posledovatel'nosti deklaracij i predlozhenij. Edinstvenno chto dolzhno byt' obyazatel'no deklarirovano eto formaty otchetov i podprogrammy (funkcii). Vse ne ob®yavlennye peremennye, massivy, imeyut znachenie 0 ili null. Deklaracii (ob®yavleniya). Pel imeet svobodnyj format. Kommentarii nachinayutsya s simvola '#' i prodolzhayutsya do konca stroki. Deklaracii mogut ispol'zovat'sya v lyubom meste programmy tak zhe kak i predlozheniya (statements) no dejstvuyut oni tol'ko v faze kompilyacii programmy. Obychno ih pomeshchayut ili v nachale ili v konce programmy. Deklaraciya podprogramm pozvolyaet ispol'zovat' imya podprogrammy kak spiskovyj operator nachinaya s momenta deklarirovaniya. Primer: sub test; # Deklaraciya podprogrammy test $var1 = test $0; # Ispol'zovanie kak operatora spiska. Deklaracii podprogramm mogut byt' zagruzheny iz otdel'nogo fajla predlozheniem require ili zagruzheno i importirovano v tekushchuyu oblast' imen predlozheniem use. Podrobno sm. glavu Moduli. Prostoe predlozhenie. Prostoe predlozhenie obyazatel'no zakanchivaetsya simvolom ';' esli tol'ko eto ne poslednee predlozhenie v bloke gde ';' mozhno opustit'. Zamet'te chto sushchestvuyut operatory takie kak eval{} i do{} kotorye vyglyadyat kak slozhnye predlozheniya no na samom dele eto termy i trebuyut obyazatel'nogo ukazaniya konca predlozheniya. Lyuboe prostoe predlozhenie mozhet soderzhat' single modifikator pered ';'. Sushchestvuyut sleduyushchie single modifikatory: if EXPR unless EXPR while EXPR until EXPR gde EXPR - vyrazhenie vozvrashchayushchee logicheskoe znachenie true ili false. Modifikatory while i until vychislyayutsya v nachale predlozheniya krome bloka do kotoryj vypolnyaetsya pervym. if EXPR - Modifikator "esli". Predlozhenie vypolnyaetsya esli EXPR vozvrashchaet true. Primer: $var = 1; $var2 = 3 if $var > 0; # Rezul'tat: $var2 = 3 while EXPR - Modifikator "poka". Predlozhenie vypolnyaetsya stol'ko raz poka EXPR = true Primer: $var = 1; print $var++ while $var < 5; # Pechat' $var s inkrementom Rezul'tat: 1234 until EXPR - Modifikator "do ". Predlozhenie vypolnyaetsya do teh por poka EXPR = false Primer: $var = 1; print $var++ until $var > 5; # Pechat' $var s inkrementom Rezul'tat: 12345 unless EXPR - Modifikator "esli ne" . Obratnyj k if. Vyrazhenie vypolnyaetsya esle EXPR = false. Primer: $var = 1; print $var++ unless $var > 5; # Pechat' $var s inkrementom Rezul'tat: 1 Slozhnye predlozheniya. Posledovatel'nost' prostyh predlozhenij ogranichennaya funkcional'nymi ogranichitelyami nazyvaetsya blokom. V Pel eto mozhet byt' celyj fajl, posledovatel'nost' predlozhenij v operatore eval{} ili chashche vsego eto mnozhestvo prostyh predlozhenij ogranichennyh kruglymi skobkami '{}'. Suzhestvuyut sleduyushchie vidy slozhnyh predlozhenij: if (EXPR) BLOCK if (EXPR) BLOCK else BLOCK if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK LABEL while (EXPR) BLOCK LABEL while (EXPR) BLOCK continue BLOCK LABEL for (EXPR; EXPR; EXPR) BLOCK LABEL foreach VAR (LIST) BLOCK LABEL BLOCK continue BLOCK Obratite vnimanie, chto slozhnye predlozheniya opisany v termah blokov a ne predlozhenij kak v yazykah C ili Pascal. Poetomu neobhodimo vsegda ispol'zovat' kruglye skobki dlya oboznacheniya bloka. if (EXPR) BLOCK - Vychislyaetsya logicheskoe vyrazhenie EXPR i esli true blok vypolnyaetsya. Primer: $var =1; if ($var == 1) { print $var,"\n"; } Rezul'tat: 1 if (EXPR) BLOCK else BLOCK2 - Esli EXPR=true vypolnyaetsya BLOCK inache BLOCK2. Primer: $var =2; if ($var == 1) { print "\$var = 1\n"; } else { print "\$var ne ravno 1\n"; } Rezul'tat: $var ne ravno 1 if (EXPR1) BLOCK1 elsif (EXPR2) BLOCK2 ... else BLOCK - Esli EXPR1=true vypolnyaetsya BLOCK1 inache esli EXPR2=true vypolnyaetsya BLOCK2 inache ... inache BLOCK. Primer: $var = 1; if ($var == 0) { print "\$var = 0\n"; } elsif ($var == 1) { print "\$var = 1\n"; } else { print "Ne izvestnoe \$var\n"; } Rezul'tat: $var = 1 Cikl while vypolnyaet BLOCK do teh por poka EXPR = true. Metka LABEL ne obyazatel'na i sostoit iz identifikatora zavershayushchegosya simvolom ':'. Metka neobhodima pri ispol'zovanii vnutri bloka cikla upravlyayushchih operatorov next, last i redo. Esli metka vse zhe otsutsvuet to eti operatory ssylayutsya k nachalu blizhajshego cikla. Blok posle continue vypolnyaetsya vsegda pered tem kak vychislyaetsya logicheskoe vyrazhenie EXPR. |to podobno EXPR3 v predlzhenii for poetomu v etom bloke udobno izmenyat' schetchiki i flagi cikla dazhe esli primenyaestya operator next. Operatory upravleniya ciklom. next - podoben continue v S. Perehodit k nachalu tekushchego cikla t.e. povtoryaet iteraciyu. Primer: M1: while ($i < 6) { ++$i; # Uvelichivaem schetchik na 1 next M1 if $i < 3; # Perehodim v nachalo esli $i < 3 ++$i; # inache uvelichivaem schetchik eshche raz na 1 } continue { print "$i "; # Pechataem $i } Rezul'tat: 1 2 4 6 last - podoben operatoru break v yazyke S. Nemedlenno preryvaet cikl. Blok continue propuskaetsya. Primer: M1: while ($i < 6) { ++$i; # Uvelichivaem schetchik na 1 last M1 if $i > 3; # Vyhod iz cikla esli $i > 3 ++$i; # inache uvelichivaem schetchik eshche raz na 1 } continue { print "$i "; # Pechataem $i } Rezul'tat: 2 4 redo - nachat' novyj cikl ne vychislyaya EXPR i ne vypolnyaya continue blok. Primer: M1: while ($i < 6) { ++$i; # Uvelichivaem schetchik na 1 redo M1 if $i == 3; # Dalee propustit' dlya $i = 3 ++$i; # inache uvelichivaem schetchik eshche raz na 1 } continue { print "$i "; # Pechataem $i } Rezul'tat: 2 5 7 Cikl for. LABEL for (EXPR1; EXPR2; EXPR3) BLOCK Operator for polnost'yu analogichen operatoru for v S. V pered nachalom cikla vypolnyaetsya EXPR1, esli EXPR2 = true vypolnyaetsya blok, zatem vypolnyaetsya EXPR3. Primer: for ($i = 2; $i < 5; ++$i) { print $i, " "; } print "\nPosle cikla i = $i\n"; Rezul'tat: 2 3 4 Posle cikla i = 5 Cikl foreach. LABEL foreach VAR (LIST) BLOCK Peremennoj VAR prisvaivaetsya poocheredno kazhdyj element spiska LIST i vypolnyaetsya blok. Esli VAR opushchenno to elementy prisvaivayutsya vstroenoj peremennoj $_. Esli v tele bloka izmenyat' znachenie VAR to eto vyzovet izmenenie i elementov spiska t.k. VAR fakticheski ukazyvaet na tekushchij element spiska. Vmesto slova foreach mozhno pisat' prosto for - eto slova sinonimy. Primer: @mesyac = ("yanvar'","fevral'","mart"); # Sozdali massiv foreach $i (@mesyac) { print $i," "; # Pechat' $i } Rezul'tat: yanvar' fevral' mart Primer: @mesyac = ("yanvar'","fevral'","mart"); # Sozdali massiv foreach $i (@mesyac) { $i = uc($i); # Pereveli v verhnij registr } print @mesyac; Rezul'tat: YANVARXFEVRALXMART Primer: for $i (3,5,7) { print "$i "; } Rezul'tat: 3 5 7 Bloki i operator switch. Blok ne zavisimo ot togo imeet on metku ili net semanticheski predstavlyaet soboj cikl kotoryj vypolnyaetsya odin raz. Poetomu dejstvie opratorov cikla next, last, redo - analogichno opisannomu vyshe. Bloki udobny dlya postroeniya switch (pereklyuchatel') struktur. V pel net special'nogo operatora switch podobnogo yazyku S poetomu vy sami mozhete sozdavat' udobnye dlya vas konstrukcii. Opyt avtora pokazyvaet chto dlya prostoty napisaniya luchshe vsego podhodit konstrukciya vida if ... elsif ... else ... hotya mozhno sochinit' i nechto podobnoe: SWITCH: { if ($i ==1 ) { .....; last SWITCH; } if ($i ==2 ) { .....; last SWITCH; } if ($i ==3 ) { .....; last SWITCH; } $default = 13; } Vybirajte sami po svoemu vkusu. Operator goto. V Pel sushchestvuet operator goto hotya gde , kak i kogda ego primenyat' kak govoril Hodzha Nasredin "Tonkij filosovskij vopros". Dlya nachinayushchih programmistov kotorym ot tak "nuzhen" ya by voobshche posovetoval "zabyt'" o ego sushchestvovanii. Odnako pri sozdanii bol'shih proizvodstvennyh zadach na poslednem etape osobenno pri otrabotke "otval'nyh" oshibochnyh situacij konechno goto nuzhen. V Pel realizovano tri formy goto. goto - metka, goto - vyrazhenie i goto - podprogramma. goto - metka vypolnyaet neposredstvennyj perehod na ukazannuyu metku. goto - vyrazhenie - Vychislyaet imya metki i delaet sootvetsvuyushchij perehod. Naprimer esli my hotim sdelat' perehod na odnu iz treh metok "M1:", "M2:" ili "M3:" v zavisimosti ot znachenij peremennoj $i ravnoj 0, 1 ili 2 to eto luchshe sdelat' sleduyushchim obrazom: goto ("M1", "M2", "M3")[$i]; zdes' $i ispol'zuetsya kak indeks massiva ukazannogo neposredstvenno v vyrazhenii. goto podprogramma - dovol'no redkij sluchaj t.k. vsegda proshche i nadezhnej vyzvat' podprogrammu "estestvennym" obrazom. POD operatory. Dokumentirovanie programm. V Pel realizovan ochen' udobnyj mehanizm dlya napisaniya dokumentacii v moment sozdaniya programmy. Dlya etogo primenyayutsya special'nye POD operatory. Esli v tele programmy interpretator vstrechaet operator nachinayushchijsya s simvola '=' naprimer: = head Nabor standartnyh procedur to propuskaetsya vse do slova '=cut'. |to udobno dlya vklyucheniya dlinnyh na neskol'ko strok ili stranic kommentariev. Zatem s pomoshch'yu special'noj programmy pod mozhno otdelit' tekst dokumentacii ot teksta programmy.  * Peremennye *  V Pel sushchestvuet tri tipa struktur dannyh: skalyary, massivy skalyarov i heshi (hashes) - associativnye massivy skalyarov. Obychno elementy massivov indeksiruyutsya celymi chislami, pervyj element - nulevoj. Otricatel'noe znachenie indeksa oboznachaet nomer pozicii elementa s konca. Heshi indeksiruyutsya strokami simvolov. Imena skalyarnyh peremennyh vsegda nachinayutsya s simvola '$' dazhe kogda oboznachayut element massiva. Primer: $var1 # Prostoj skalyar 'var1' @var1[0] # Pervyj element massiva 'var1' $var1{'first'} # |lement hesha s indeksom 'first' V sluchae ispol'zovaniya imeni massiva "celikom" ili ego "sreza" pered imenem massiva stavitsya simvol '@'. Primer: @var1 # Vse elementy massiva var1 ( $var1[0], $var1[1], ... $var1[n]) @var1[1,3,10] # |lementy $var1[1], $var1[3], $var1[10] @var1{'first','last'} # to zhe chto i ( $var1{'first'}, $var1{'last'} ) Hesh "celikom" nachinaetsya s simvola '%'. Primer: %var, %key, %years Imena podprogramm nachinayutsya simvolom '&' esli iz konteksta ne vidno chto eto podprogramma. Primer: &sub1, &test_prog, test(12) Imena tablic simvolov vsegda nachinayutsya simvolom '*'. Kazhdyj tip peremennyh imeet svoyu oblast' pamyati poetomu $var1 i $var1[0] sovershenno raznye peremennye, hotya $var1[0] chast' massiva @var1. Tak zhe\ @var1 i %var1 - raznye massivy peremennyh. Imena peremennyh mogut soderzhat' lyubye bukvenno-cifrovy simvoly za isklyucheniem probela i tabulyacii. |ti smvoly ispol'zuyutsya v kachestve razdelitelej. Bol'shie i malye bukvy razlichayutsya poetomu $var1 i $Var1 - raznye peremennye. V Pel po umolchaniyu imena metok i ukazatelej fajlov pishut bol'shimi bukvami. Kontekst. Bol'shoe znachenie dlya pravil'nogo upotrebleniya vstroennyh funkcij imeet kontekst ispol'zovaniya rezul'tata etih funkcij t.k. v protivnom sluchae oni vozvrashchayut sovershenno "neponyatnyj" rezul'tat. V Pel imeetsya dva glavnyh konteksta: skalyarnyj i spisok (list). Proshche govorya esli v levoj chasti vyrazheniya imeetsya vvidu odno edinstvennoe znachenie - to eto skalyarnyj kontekst. Esli mnozhestvo znachenij - spisok. Primer: $var1 = <>; # Prochitat' odnu stroku fajla @var1 = <>; # Prochitat' vse stroki fajla v massiv @var1 $var1 = (1,2,3); # $var = 3 - kolichestvo elementov @var1 = (1,2,3); # Sozdanie massiva @var1 s elementami 1,2,3 Skalyarnye znacheniya. Vse dannye v Pel eto skalyary, massivy skalyarov i heshi skalyarov. Skalyarnye peremennye mogut soderzhat' chisla, stroki i ssylki. Preobrazovanie chisla - stroki proishodit avtomaticheski po umolchaniyu. Skalyar mozhet imet' tol'ko odno edinstvennoe znachenie, hotya eto mozhet byt' ssylka na massiv skalyarov. Tak -kak Pel sam preobrazovyvaet chisla v stroki i naoborot to programmistu net neobhodimosti dumat' o tom chto vozvrashchaet funkciya. V Pel ne sushchestvuet tipov "stroka" ili "chislo" ili "fajl" ili chto to eshche. |to kontekstno zavisimyj polimorfnyj yazyk dlya raboty s tekstami. Skalyar imeet logicheskoe znachenie "TRUE" (istina) esli eto ne nulevaya stroka ili chislo ne ravnoe 0. V Pel sushchestvuet dva tipa nulevyh (null) skalyarov - opredelennye (defined) i ne opredelennye (undefined). Ne opredelennoe znachenie vozvrashchaetsya kogda chto-to ne sushchestvuet. Naprimer ne izvestnaya peremennaya, konec fajla ili oshibka. S pomoshch'yu funkcii defined() vy mozhete zaranee obnaruzhit' podobnoe sostoyanie. Kolichestvo elementov massiva tak zhe yavlyaetsya skalyarom i nachinaetsya simvolami $# podobno interpretatoru csh. Fakticheski $#var1 - eto indeks poslednego elementa massiva. Nuzhno pomnit' chto pervyj element imeet indkes 0 poetomu kolichestvo elementov opredelyaetsya kak $#var1+1 . Prisvoenie znacheniya $#var1 - izmenit dlinu massiva i razrushit "ostavlennye" znacheniya. Prisvoenie znacheniya elementu massiva s indeksom bol'she chem $#var1 - uvelichit razmer massiva, a prisvoenie emu nulevogo spiska - obnulit. V skalyarnom kontekste imya massiva vozvrashchaet ego dlinu (dlya spiska vozvrashchaetsya poslednij element). Primer: @var1 = (4, 3, 2, 1); # Prisvoenie znacheniya elementam massiva $i = @var1; # Ispol'zovanie skalyarnogo konteksta print $i; # Pechat' rezul'tata 4 - kol-vo elementov print @var1; # Spiskovyj kontekst, pechat' vseh elementov. Dlya prinuditel'nogo polucheniya skalyarnogo znacheniya udobno primenyat' funkciyu scalar(). Primer: print scalar(@var1); # Vyvod dliny massiva a ne ego znachenij Hesh v skalyarnom kontekste vozvrashchaet "true" esli sushchestvuet hotya by odna para "klyuch-znachenie". Fakticheski vozvrashchaetsya stroka tipa 2/8 gde 8 - kolichestvo vydelennyh "yacheek" pamyati a 2 - kolichestvo ispol'zovannyh. Konstruktory skalyarov. CHisla pishutsya standartno: 123 123.123 0.12 .12E-10 0xABCD # SHestnadcetirichnaya zapis' 0377 # Esli 0 v nachale - vos'merichnaya 123_456_123 # Tak tozhe mozhno dlya udobstva chteniya. Stroki ogranichivayutsya odinarnymi (') ili dvojnymi (") kavychkami: 'Rovnyajs', smirno!' "Postroemsya i spasemsya." Sposobov oboznacheniya strok ochen' mnogo. Plodrobno smotrite opisanie operatora qq. V heshe mozhno opuskat' kavychki esli indeks ne soderzhit probelov. Primer: $var1{first} to zhe chto i $var1{'first'} Obratite vnimanie na to chto pered pervoj odinarnoj kavychkoj dolzhen stoyat' probel inache stroka vosprimetsya kak imya peremennoj tak-kak v imenah razresheno ispol'zovanie odinarnyh kavychek. Zapreshchaetsya v kavychkah primenyat' zarezervirovannye literaly __LINE__ (nomer tekushchej stroki programmy), __FILE__ (tekushchij fajl). Dlya oboznacheniya konca programmy mozhno primenyat' literal __END__ Ves' posleduyushchij tekst ignoriruetsya, no ego mozhno prochitat' ispol'zuyu ukazatel' fajla DATA. Slova v programme ne poddayushchiesya ni kakoj intepretacii vosprinimayutsya kak stroki v kavychkah poetomu rekomenduetsya imena metok i ukazatelej fajlov pisat' bol'shimi bukvami dlya izbezhaniya vozmozhnogo "konflikta" s zarezervirovannymi slovami. V Pel est' vozmozhnost' vstavlyat' tekst dokumenta pryamo v programmu. Tak nazyvaemyj "here-doc" (zdes' tekst) metod. Oboznachaetsya simvolami << za kotorym idet slovo-ogranichitel'. Primer: print <<EOF; # Vse stroki do EOF - tekst dlya pechati. |j vy troe, idite dvoe syuda! Polkovnik Savon'kin. EOF Konstruktory spiskov. Spisok - mnozhestvo znachenij perechislennyh cherez zapyatuyu i zaklyuchennyh v kruglye skobki. V spiskovom kontekste spisok vozvrashchaet poslednij element spiska. Primer: @var1 = (1, 2, 'privet', 1.2); # Prisvoit' znachenie elementam. gde $var1[0] = 1, $var1[1] = 2, $var1[2] = 'privet' $var1[3] = 1.2 $var1 = (1, 2, 'privet', 1.2); a zdes' $var1 = 1.2 t.e. poslednee znachenie spiska. Dopuskaetsya primenyat' v spiske drugie spiski, no v poluchennom spiske uzhe nevozmozhno razlichit' nachalo i konec vklyuchennyh spiskov. Primer: @s1 = (1, 2, 3); # Pervyj spisok @s2 = (6, 7, 8); # Vtoroj @s = (0, @s1, 4, 5, @s2, 9, 10); # Vklyuchaem spiski @s1 i @s2 print @s; # Rezul'tat: 012345678910 - znacheniya bez probelov. Spisok bez elementov oboznachaestya kak () i nazyvaetsya nul'-spiskom. Spiskovoe vyrazhenie mozhno upotreblyat' kak imya massiva, no pri etom ego nuzhno brat' v kruglye skobki. Primer: print ('yanvar'','fevral'','mart')[1]; Rezul'tat: fevral' Spisok mozhet byt' prisvoen spisku tol'ko esli kazhdyj element v spiske v levoj chasti vyrazheniya dopustim po tipu spisku v pravoj chasti. Primer: ($a, $b, $c) = (1, 2, 3); # $a = 1, $b = 2, $c = 3 Prisvaivanie spiskov v skalyarnom kontekste vozvrashchaet kolichestvo prisvoennyh elementov. Primer: $x = (($a, $b, $c) = (1,2)); # Rezul'tat $x=2 V sluchae prisvaivaniya spiska heshu spisok razsmatrivaetsya kak pary: klyuch-znachenie. Primer: %dni_mesyaca = ('yanvar'', 31, 'fevral'', 30); Rezul'tat: $dni_mesyaca{yanvar'} = 31, $dni_mesyaca{fevral'} = 30 Dlya udobstva zapisi mozhno ispol'zovat' vyrazhenie s => . Primer: %dni_mesyaca = ( yanvar' => 31, fevral' => 30, ); Tip typeglobs V Pel ispol'zuetsya special'nyj vnutrennij tip typeglog dlya zapisi massiva vseh peremennyh. Takie massivy nachinayutsya s simvola '*'. Ih udobno primenyat' dlya peredachi ssylok na massivy i heshi, no v dannoj versii Pel uzhe est' vozmozhnost' primenyat' ssylki poetomu eto delaetsya ochen' redko. Edinstvenno gde eto neobhodimo tak eto dlya raboty so ssylkami na fajly. Naprimer esli vam nuzhno sozdat' lokal'nuyu ssylku na fajl v procedure to eto luchshe sdelat' tak: sub new_sub { local *IN; # Ssylka na fajl open (IN, "test") || return undef; # Otkryt' fajl. Vozvrat pri oshibke. ......... return; } Bolee podrobno eto opisano v glave Ssylki.  * Vstroennye peremennye Pel *  Opisannye v dannoj glave peremennyye imeyut v Pel special'nye znacheniya. Oni oboznachayutsya neskol'ko neprivychno dlya "glaza" programmistov t.k. sostoyat obychno tol'ko iz dvu simvolov prichem pervyj eto '$' simvolo s kotorogo nachinayutsya imena vseh peremennyh i proizvol'nyj chasto ne bukvenno-cifrovoj simvol. Esli vy hotite pol'zovat'sya ih "normal'nymi" bukvennymi sinonimami to vam nuzhno ukazat' v nachale programmy: use English; Tochno tak zhe esli vy zahotite pol'zovat'sya peremennymi i metodami tekushchego ukazatelya fajlov vy mozhete napisat': use FileHandle; posle etogo mozhno mozhno prosto pisat': metod ukazatel' vyrazhenie ili ukazatel' -> metod(vyrazhenie) Nizhe privodyatsya imena kak v korotkoj tak i v dlinnoj (slovesnoj) forme. Nekotorye iz vstroennyh peremennyh imeyut dostup to'ko na chtenie poetomu izmenit' ih znachenie prosto ne vozmozhno. $_ $ARG Peremennaya - po umolchaniyu dlya operatorov vvoda i poiska. To est' esli v kachestve argumenta ne ukazana nikakaya peremennaya to ispol'zuetsya imenno eta. $cifra Soderzhit najdennye podstroku v poslednem poiske kogda shablon soderzhit metasimvoly v kruglyh skobkah. Cifra v dannom sluchae eto nomer skobok. Pervaya podstroka imeet nomer 1. $& $MATCH Najdennaya podstroka v poslednem poiske po shablonu. $` Podstroka predshevstvuyushchaya najdennoj podstroke. $' $POSTMATCH Podstroka posleduyushchaya za najdennoj podstrokoj. $+ $LAST_PAREN_MATCH Podstroka najdennaya v poiske s vyborom po "ili". $* $MULTILINE_MATCHING Esli znachenie etoj peremennoj ustanovit' ravnym 1 to peremennaya v kotoroj osushchestvlyaetsya poisk budet schitat'sya mnogostorochnoj t.e. soderzhashchej simvoly '\n' - perevod stroki. Esli znacheie ravno 0 to peremennaya schitaetsya odnostrochnoj. V Pel versii 5 i vyshe ne rekomenduestya ispol'zovat' etu peremennuyu. $. $INPUT_LINE_NUMBER $NR Nomer prochitannoj stroki poslednego operatora vvoda. Zakrytie fajla vyzyvaet ochistku znacheniya etoj peremennoj. $/ $RS $INPUT_RECORD_SEPARATOR Simvol - priznak konca vhodnoj stroki. Po umolchaniyu eto '\n' $| $OUTPUT_AUTOFLUSH Esli prisvoit' etoj peremennoj ne nulevoe znachenie to budet sbros bufera vyvoda posle kazhdoj operacii vyvoda. Znachenie po umolchaniyu -0 $, $OFS $OUTPUT_FIELD_SEPARATOR Simvol dobavlyaemyj operatorom print posle kazhdogo elementa iz spiska parametrov. $\ $ORS $OUTPUT_RECORD_SEPARATOR Simvol dobavlyaemyj print posle vyvoda vseh parametrov. $" $LIST_SEPARATOR Anologichen "$," no dobavlyaetsya posle kazhdogo elementa massiva ukazanoogo v "....". $; $SUBSEP $SUBSCRIPT_SEPARATOR Simvol - razdelitel' dlya emulyacii mnogomernyh massivov v hesh massivah. Po umolchaniyu '\034'. $# $OFMT Format po umolchaniyu dlya vyvoda chisel. $% $FORMAT_PAGE_NUMBER Format po umolchaniyu dlya vyvoda nomerov stranic. $= $FORMAT_LINES_PER_PAGE Dlina odnoj stranicy. Po umolchaniyu 60 strok. $- $FORMAT_LINES_LEFT Kolichestvo ostavshihsya strok na stranice. $~ $FORMAT_NAME Imya formata tekushchego vyvoda. Po umolchaniyu imya ukazatelya. $^ $FORMAT_TOP_NAME Imya tekushchego formata dlya zagolovka stranicy. $: $FORMAT_LINE_BREAK_CHARACTERS Simvoly perenosa stroki dlya mnogostrochnyh polej. V stroke formata takie polya nachinayutsya simvolom '^'. Po umolchaniyu '\n-'. $^L $FORMAT_FORMFEED Simvol perevoda formata ( smeny lista). Po umolchaniyu '\f'. $^A $ACCUMULATOR Tekushchee znachenie akkumulyatora funkcii write() dlya format(). Znachenie etoj peremennoj mozhno uvidet' tol'ko pri ispol'zovanii funkcii formline() t.k. write() ochishchaet ee posle kazhdogo vyvoda. $? $CHILD_ERROR Dannaya permennaya soderzhit status zaversheniya takih processov kak: zakrytie pipe, zavershenie funkcij system(), wait() i `...`. $! $ERRNO $OS_ERROR V chislovom kontekste vozvrashchaet kod oshibki errno. V strokovom - stroku soobshcheniya ob oshibke. Mozhno prinuditel'no prisvoit' etoj permennoj kod oshibki chto by poluchit' sistemnoe soobshchenie dlya dannogo koda ili ustanovit' kod zaversheniya dlya funkcii die(). $@ $EVAL_ERROR Soobshchenie ob oshibke poslednej komandy eval(). $$ $PID $PROCESS_ID Nomer tekushchego processa. $< $UID $REAL_USER_ID Real'nyj UID tekushchego processa. $> $EUID $EFFECTIVE_USER_ID |ffektivnyj UID tekushchego processa. $( $GID $REAL_GROUP_ID Real'nyj GID tekushchego processa. $) $EGID $EFFECTIVE_GROUP_ID |ffektivnyj GID tekushchego processa. $O $PROGRAM_NAME Imya fajla programmy. Esli etoj peremennoj prisvoit' kakoe nibud' znachenie to ego mozhno videt' v komande ps, chto udobno dlya kontrolya za sostoyaniem programmy. $[ Nomer pervogo elementa massiva ili simvola stroki. Znachenie po umolchaniyu - 0. $] $PERL_VERSION Stroka soobshchenie versii Pel. Pechataetsya po komande perl -v Primenyaetsya v programme dlya opredeleniya rabochej versii Pel. V chislovom kontekste eto nomer versii plyus nomer modifikacii / 1000. $^D $DEBUGGING Tekushchee znachenie klyucha otladki '-D'. $^F $SYSTEM_FD_MAX Nomer maksimal'nogo sistemnogo opisatelya fajlov (system file descriptor). Obychno eto 2. $^I $INPLACE_EDIT Tekushchee znachenie inplace-edit vozmozhnosti. Dlya otklyucheniya ispol'zujte undef. $^P $PERLDB Vnutrennij flag otladki. Primenyaetsya dlya togo chto by otladchik ne otslezhival samogo sebya. $^T $BASETIME Vremya v sekundah s nachala 1970 goda starta tekushchej programmy. $^W $WARNING Znachenie flaga '-w'. true -esli vklyucheno i false - vyklyucheno. $^X $EXECUTABLE_NAME Komanda zapuska Pel. Analogichno argv[0] v S. $ARGV Imya tekushchego fajla chitaemogo operatorom '&lt;>'. @ARGV Massiv parametro