* | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Perl MagyarulA programozó három fõ erénye a Lustaság, a Türelmetlenség és az Önhittség. Mottó után megnézhetjük, hogy egyáltalán mirõl lesz szó:
Perl 5 nyelv rövid összefoglalásaA Perl nyelv elsõ verzióját 1991-ben készítette el Larry Wall, a NASA támogatásával. A nyelvet elsõsorban szöveg feldolgozásra szánták. Sokkal fontosabbnak tekintették a hatékonyságot mind a kód megírásában, mind a kész program futtatásakor, mint a szépséget. A nyelv neve is a fentebb elmondottakra utal, hiszen a Perl a "Practical Extraction and Report Language" -bõl képzett betûszó. Igaz, az Larry Wall elõször "Pathologically Eclectic Rubbish Lister"-nek titulálta.A nyelv nagy elõnye a platformfüggetlenség: létezik az összes U*X-ra, VMS-re, OS/2-re és az M$ termékeire is. A Perl nyelv egy interpretált - illetve betöltéskor fordított - nyelv. Eredetileg rendszeradminisztrációs feladatok megkönnyítésére írta Larry Wall, mert nem volt kedve a meglévõ eszközök korlátaival bajlódni. A nyelv meglévõ eszközökre lett alapozva: C, sed, awk és sh programokra. Szerintem a LISP ismerete is sokat segíthet a listakezelések megértésében. Perl-ben csak a számítógép hardware korlátai érvényesülnek: egy teljes file-t képes beolvasni egy string változóba (ha van elég memória), tetszõleges mélységû rekurzió futtatható benne (ha van türelmünk és memóriánk). Asszociatív tömbök elérését hash táblákkal gyorsítja (ami meglepõen hatékony programok írását teszi lehetõvé). Nagyon gyors és rugalmas mintaillesztõ algoritmusa van szövegek keresésére és cseréjére. Képes bináris adatokkal is dolgozni, és ezekbõl bonyolult adatstruktúrákat felépíteni. Az adminisztrációs feladatok megkönnyítésére az aszociatív tömbökhöz adatbázis file-okat rendelhetünk, melyek szerkezetét egy gyakorlott programozó maga is megadhatja. Az 5-ös verziótól kezdve már használhatjuk a moduláris programozást támogató nyelvi konstrukciókat, sõt már Objektum Orientált eszközöket is. A Perl-ben setuid programok sokkal biztonságosabban írhatók, mint C nyelvben az adatfolyam követését biztosító funkciók miatt (ld.: -T kapcsoló). Elkerülhetünk egy csomó egyszerû hibát, amit a C programban csak debuggolással fedeznénk fel. Egyszerûen sokkal jobb a fejlesztési idõ/futtatási idõ arány, ha egy ritkán használt, vagy futási idõben nem kritikus program írásánál. Szerintem akkor is érdemes ehhez a nyelvhez fordulni, ha egy shell script-ekbõl és C programokból álló keveréket szeretnénk létrehozni, vagy csak tesztelni szeretnénk egy ötletünket, amit - ha beválik - persze késõbb megírhatunk C-ben. Fontos még megjegyezni, hogy a Perl POSIX kompatíbilis. Ez a leírás UNIX rendszert használó gépeken használható fel igazán. A konkrét nyelvi részek a DOS, OS/2 és Windows alatt futó Perl interpreterekre is igaz, de a környezetfüggõ részek és a példák csak UNIX alapú rendszereken mennek. Ennyit a "rövid" összefoglalásról... IndulásKezdetnek mindjárt megnézhetjük a minimális Perl programot, ami a "Hello World!!!" szöveg kiírásához kell:#!/usr/local/bin/perl print "Hello World!!!\n";Már ebbõl a picike programból egy csomó hasznos dolgot meg lehet tudni:
AdatstruktúrákHárom alapvetõ adatstruktúra található a nyelvben: skalár, skalárok tömbje és az asszocitív tömb. Ezeket - mint azt késõbbiekben látni fogjuk - mutatókkal is lehet kombinálni, így lényegében mindenféle adatstruktúrát megalkothatunk. A normál tömbök indexe - általában - 0-val kezdõdik. Az asszociatív tömböket szövegekkel kell indexelni.A változó nevének elsõ karaktere határozza meg annak típusát:
Példák: $days # egyszerû skalár $days[3] # days nevû tömb negyedik eleme @days # az egész tömb ($days[0], .. , $days[$#days]) $days{'Feb'} # days nevû asszociatív tömb egy eleme %days # az egész asszociatív tömb (kulcs, érték párok) $#days # days tömb utolsó indexeAz alprogramokat még a & jellel is megjelölhetjük. Erre akkor lehet szükség, ha az alprogramot deklarációja elõtt szeretnénk használni. Függvényre a deklarációja után már a & szimbólum nélkül is hivatkozhatunk (ez - a nyelv elõzõ verziójától eltérõen - minden függvényre alkalmazható). A változók nevei egyébként a típusuknak megfelelõ külön szimbólumtáblába kerülnek, tehát használhatunk azonos nevû tömböt, asszociatív tömböt és skalárt. (Ekkor $ize[0] az @ize tömb része, nem pedig az $ize változót helyettesíti.) A változók nevei betûvel kell hogy kezdõdjenek, és tetszõleges alfanumerikus karakterrel, illetve aláhúzásjellel folytatható. A változó neve nem kell, hogy megadott legyen, akár egy kifejezés is állhat helyette, melynek aktuális értéke lesz a valódi név! Vannak speciális változónevek alapvetõ paraméterek jelölésére. Ezek az KörnyezetA kifejezés típusa a kifejezés környezetétõl is függhet!Például az int(<STDIN>) eredménye egy egész szám lesz, amit a bemenet egy sorából állít elõ az int függvény, de a sort(<STDIN>) eredménye egy lista lesz, amit a bemenet összes sorának beolvasása után a sort függvény rendezéssel állít elõ! SkalárokSkalár változók sokféle értéket tárolhatnak: szám, szöveg, bináris adat vagy mutató. A tartalom a használat során mindig szükséges formára alakul, azaz kiírhatunk egy számot szövegként egy változóba, majd ezt a változót megszorozhatjuk kettõvel.Az aritmetikai mûveleteknél a számok bináris formára konvertálódnak, így ezek pontosságát a processzor korlátozza. Vannak persze kiegészítõ modulok tetszõleges pontosságú számok kezelésére is. Feltételek vizsgálatánál csak az üres szöveg, illetve a 0 érték jelent hamisat. A skalár változóknak alapvetõen két állapota lehet: definiált, vagy definiálatlan. Ezeket a defined, illetve undefined függvényekkel kérdezhetjük le. Egy változó addig definiálatlan, amíg valaki nem ad neki értéket, vagy nem definiálja explicit módon. Definiálatlan változónak - a környezetétõl függõen - 0 vagy üres szöveg értéke van. Példák: $i = 2; # egész $f = 2.3; # racionális $szam = 1000000000; # ez egy nagy egész $hexa = 0xffeedd; # hexadecimális szám $szoveg = "Ez egy szoveg"; # egy szöveg print "Valami\n"; # egy szöveg megjelenítése print <<VEGE; # hosszabb szöveg megjelenítése Valami # "Itt a dokumentum" stílusú VEGE # adatbevitellel $szoveg = <<VEGE; # $szoveg = "ez is szoveg\n" ez is szovega # ez is megy VEGE fv(<<EGY, <<KETTO); # sõt ez is! elso parameter EGY masodik parameter KETTO TömbökA Perl-ben használt tömböket inkább indexelt listáknak kéne nevezni a kiterjeszthetõségük miatt. Ha bármelyik típusban egy eddig nem létezõ elemnek adunk értéket az automatikusan definiálódik. A tömböket persze nem csak elemenként lehet feltölteni:@tomb = ('elso', 2, $harom); # háromelemû tömb %szinek = ( # asszociatív tömb 'piros' => 0x00f, 'kék' => 0x0f0, 'zöld' => 0xf00, );Értékadásokban (rész)tömböket is értékül adhatunk. Ezekben az esetekben a balérték listája az elsõ elemtõl kezdve addig töltõdik fel, amíg van új elem a jobb oldalon. Tömbök tömbje nem létezik perlben, így a (@foo1, @foo2, @bar) a @foo1 , @foo2 és a @bar ltömb kompozíciója, míg a ((), () , ()) és a () ugyan azt - az üres tömböt - jelentik. Szintaxis ... utasításokA Perl program utasítások és deklarációk egymásutánja, amelybe megjegyzéseket a # jel használatával tehetünk. Ennek hatására a Perl interpreter a sor végéig lévõ szövegrészt megjegyzésnek tekinti.A nyelvben az utasítások és deklarációk szabadon - akár keverve is, mint egy C++ programban - követhetik egymást. Megkötés csak az alprogramok hívására van: a még nem deklarált alprogramot csak a & szimbólum használatával lehet meghívni. Egyszerû utasításEgy utasítás egy pontosvesszõvel lezárt jelsorozat lehet. Ezekbõl több is szerepelhet egy sorban. Egy utasítás után egy módosító kifejezés állhat, amely ennek az egyetlen utasításnak a hatását befolyásolja:utasítás if EXPR utasítás unless EXPR utasítás while EXPR utasítás until EXPREgy üzenet kiírása feltételtõl függõen: print "Hello kedves olvasó!\n" if $bobeszedu_program; Összetett utasításItt kell megemlíteni a BLOKK fogalmát, amely { és } jelekkel közbezárt utasítássorozat. (Itt fontosak a { és } jelek, még egyetlen utasításnál is!)Ez alapján a lehetséges formák: if (EXPR) BLOKK # BLOKK végrehajtódik ha az EXPR igaz if (EXPR) BLOKK1 else BLOKK2 # ha EXPR igaz akkor BLOKK1, egyébként BLOKK2 # lesz végrehajtva if (EXPR) BLOKK elsif (EXPR) BLOKK ... else BLOKKAz if utasítás szintaxisa itt egyértelmû lesz, mivel a BLOKK nem állhat egyetlen utasításból. CIMKE while (EXPR) BLOKK CIMKE while (EXPR) BLOKK continue BLOKKA while ciklus törzsében végrehajtott next utasítás hatására a vezérlés a continue BLOKK-ra kerül, majd újra elindul a ciklusmag. CIMKE for (EXPR1; EXPR2; EXPR3) BLOKKEz a szokásos C-beli ciklus formája. A következõ két forma ekvivalens: for($i = 1; $i < 10; $i++) { $i = 1; ... while($i < 10) { } ... } continue { $i++; } CIMKE foreach változó (TOMB) BLOKKEz a shell-ekben meglévõ ciklus egy változata. Itt a változó sorban felveszi a TOMB elemeit értékül, és így indul el a ciklusmag. CIMKE BLOKK continue BLOKKEz a végtelen ciklus volt... A switch utasításra nincs külön forma, de van rá egypár lehetséges más megoldás, például: SWITCH: { /^abc/ && do { $abc = 1; last SWITCH; }; /^def/ && do { $def = 1; last SWITCH; }; /^xyz/ && do { $xyz = 1; last SWITCH; }; $nothing = 1; }Ahol a last utasítás a megnevezett BLOKK elhagyására szolgál. A /^abc/ alakú feltételek mintaillesztésre szolgálnak. Ha egy minta illeszkedik a $_ változó tartalmához, akkor a hozzá tartozó feltétel második tagja is kiértékelésre kerül, azaz a do blokk is végrehajtódik. Operandusok és precedenciájukA C nyelvben érvényes szabályok érvényesek, és még van egypár - shell script-ekbõl ismerõs - új operátor.
Itt csak az ismeretlennek tûnõ operátorokat fogom kiemelni:
cmp értéke -1, 0, vagy 1 lehet a szövegektõl függõen.
while(<STDIN>) { print $_; # print; is lehetne, hiszen az $_ az # alapertelemezett argumentum } A szövegekhez még járul egypár "idézõjel" operátor
MintaillesztésSzövegkeresés netovábbja. HasználatA mintaillesztést több dologra is lehet használni a =~ vagy a !~ operátorokkal:
Pl.: $sor =~ /keresettszo/; Pl.:$sor =~ s/eredeti/ujszo/; MódosítókA // után általában írhatunk valamilyen karaktert, ami a keresést egy kicsit módosítja:
Az i módosító használatával így a /perl/i kifejezés a PeRL szövegre is illeszkedni fog. Az x módosító tulajdonképpen arra jó, hogy egy kicsit lazább szintakszissal írhassuk le a keresõ kifejezéseket. Ezzel már lehetõség van többsoros, sõt megjegyzésekkel tûzdelt kifejezés írására is! Regular Expressions, reguláris kifejezésekEgy ilyen kifejezésben egy szöveghez illeszthetõ mintát lehet leírni. Ebbe a mintába persze belevehetünk extra dolgokat is, hogy a nekünk szükséges részt nyerjük ki a szövegbõl. (A UNIX grep parancsában megszokott dolgok a () csoportosító operátortól eltekintve.)Az alapok
A . csak akkor fog az újsor karakterhez illeszkedni, ha erre az s módosítóval külön megkérjük, pl.: $szoveg = <<VEGE; Tobbsoros szoveg, amelyben a PERL perl szavakat kell majd megtalalni. VEGE print "illeszkedik/s\n" if $szoveg =~ /PERL.perl/s; # igaz print "illeszkedik/\n" if $szoveg =~ /PERL.perl/; # hamisA sor eleje és vége inkább rekord elejét és végét jelenti, hiszen a nyelvben meg lehet határozni, hogy mi válassza el a sorokat ($*). Alapesetben ez persze az újsor karakter, de ezt meg lehet változtatni... karaktersorozatok Egy egyszerû kifejezés ismétlõdését a következõkkel lehet jelölni:
Alapértelmezés szerint ekkor a leghosszabb ismétlõdés fog illeszkedni ezekhez a részekhez. Ha minimális számú illeszkedést szeretnénk, akkor mindegyik után odatehetjük a ? jelet: "hhhhhh" =~ /h{2,4}/; # itt "hhhh" fog illeszkedni "hhhhhh" =~ /h{2,4}?/; # itt csak "hh" Speciális karakterek
Az x módosító használatával még lehet használni más dolgokat is, de ezek szerintem már csak igen-igen ritkán kerülnek elõ. CsoportosításHa egy szövegbõl részeket ki akarunk nyerni, akkor a () karaktereket kell használnunk. Ha ezekkel bezárunk egy karaktersorozatot a reguláris kifejezésben, akkor az ahhoz illeszkedõ karakterekre a kifejezésen kívül is hivatkozhatunk.Ha egy csere környezetben használjuk, akkor az így kapott karaktersorozatokra a $1, $2, $3 ... változókkal lehet hivatkozni: s/^([^ ]*) *([^ ]*)/$2 $1/; # elsõ két szó felcserélése if(`date` =~ /(..):(..):(..)/) { # idõ kiírása print "ora: $1, perc: $2, masodperc: $3\n"; }Ha lista környezetben használjuk az illesztést, akkor a kiválasztott értékeket közvetlenül is megkaphatjuk: ($ora, $perc, $masodperc) = (`date` =~ /(..):(..):(..)/); Beépített függvényekEz a rész iszonyú nagy, és csomó olyan információt tartalmaz, amit már amúgy is ismer az ember (legalábbis a C programokban használta már õket). Itt csak néhány speciális dolgot fogok ismertetni, ami Perl jellegzetesség.Ha valaki ismeri a szokásos C függvényeket, akkor azokat bátran használhatja, biztosan megvannak. Ha nem úgy viselkedik, ahogy várta, akkor érdemes igénybe venni a POSIX modult: use POSIX;Ezek után már biztosan meglesz az összes POSIX függvény. Ha valakinek még ez sem elég, akkor igénybe veheti a különbözõ modulokat. Már a nyelvvel együtt lehet találni adatbáziskezelõ kiterjesztésektõl kezdve a terminálkezelõ függvényekig sok mindent. Ezeken kívül az Internetben legalább száz új modul kínál kiterjesztéseket különféle nyelvek és könyvtárak felé (pl.: SQL adatbázikezelés, X11 grafikus felület, Prolog...). néhány függvény...
($package, $filename, $line) = caller; while(<>) { chop; # $_ végérõl vág ... } chop($cwd = `pwd`); # aktuális könyvtár Ez a módja egy Perl prgram "fordításának". while(($key,$value) = each %ENV) { print "$key=$value\n"; }környezeti változók kiírása (ld. még a változókat) sub kiir { my ($szoveg1, $szoveg2) = @_; chop $szoveg1; chop $szoveg2; print $szoveg1, ':', $szoveg2, '\n\n'; } open(FILE,"valami.txt"); # írás-olvasás open(BE,"</etc/passwd"); # olvasás open(KI,">/tmp/output"); # írás open(FINGER,"finger @augusta |"); # olvasás pipe-ból open(RENDEZ,"| sort >/tmp/ki");# írás pipe-baAz így megnyitott file-okat a close-val lehet lezárni, és I/O mûveletekben lehet használni: print FILE "Egy szor\n"; # "Egy sor" írása a FILE-ba $sor = <BE> # sor olvasása A PACKAGENAME modulban a változó típusától függõen különbözõ függvényeket kell megírni: A no kulcsszó a use ellentettje, azaz a láthatóságot megszünteti. Elõre definiált változókawk-on nevelkedett emberek itt otthon érezhetik magukat.Ha az awk-os neveket szeretnénk használni, akkor a use English;sort kell még beírni a programba. A file-ok "objektum-szerû" használatához a use FileHandle;sort kell beírni. Ezek után a következõk ekvivalensek: print KIMENET "Hello World!!!\n"; KIMENET->print("Hello World!!!\n");A változókból itt is csak a legfontosabbakat fogom megemlíteni:
Ez persze írható változó, tehát a $> = 0; a root-tá válás egy módja, csak ez nem mindig fog bejönni :-). print "Otthonom: ", $ENV{"HOME"}, "\n"; sub handler { # az elsõ paraméter a signal neve local($sig) = @_; print "Elkaptam $sig-t!\n"; exit(0); } $SIG{'INT'} = 'handler'; $SIG{'QUIT'} = 'handler'; &nb>Néhány Perl-beli esemény is kezelhetõ így. A $SIG{__WARN__} a warn által kiváltott, a $SIG{__DIE__} pedig a die által kiváltott esemény lekezelésére szolgál. Mindkét esetben átadásra kerülnek a warn, illetve a die paraméterei. Alprogramok írásaAlprogramok deklarálása:sub NEV; # a NEV ismertté tétele sub NEV BLOCK # deklarálás és definícióEgy alprogramot nem kell elõre deklarálni ahhoz, hogy használhassuk. Az alprogramoknál a paraméterlistát sem kell deklarálni, mert ez változhat. A hívott alprogram a paramétereket a @_ listán keresztül kapja meg. Az alprogram utolsó utasításának az értéke lesz a visszatérési érték, hacsak nincs egy return utasításban más megadva. sub max { my $max = pop(@_); foreach $elem (@_) { $max = $elem if $max < $elem; } $max; } Alprogram hívása:&NEV; # az aktuális @_-t adja tovább &NEV(LISTA); # Ha &-t írunk, akkor () kötelezõ NEV(LISTA); # & elhagyható ha van () vagy már deklarált NEV LISTA; # () elhagyható, ha a NEV már deklaráltAlprogram hívása akkor megy ilyen egyszerûen, ha az az õt tartalmazó modulban látható. Ha ettõl eltérõ modulban lett deklarálva, akkor modulhivatkozással, vagy valamilyen objektum-orientált technikával kell meghívni a kívánt eljárást (ld. késõbb). $m = &max(1,2,3); # a hatás ugyan az $m = max 1 2 3; Névtelen alprogram létrehozása:$alpref = sub BLOCK; # deklarálás &$alpref(1,2,3); # hívásEz a technika fõleg egyszer használatos alprogramoknál lehet hasznos, például egy signal kezelõ átdefiniálásakor. ModulokJa kérem, ez egy "komoly" nyelv! packageA Perl nyelv lehetõséget ad különbözõ léthatósági körök használatára. Ezeket a láthatósági köröket moduloknak nevezhetjük, amelyet a package kulcsszó vezet be. A package hatása az adott blokk végéig, vagy a következõ package-ig tart.Alap esetben egy egyszerû programban minden a main modulba kerül be. Ha leírjuk a package szót, akkor az ez után következõ deklarációk már az új modulba fognak tartozni. A modul neveihez a :: hivatkozás operátorral férhetünk hozzá (ez régen egy ' jel volt, de az egyszerûbb olvashatóság érdekében, meg a C++ programozók kedvéért ez megváltozott). $elso = 1; # ez a $main::elso package MODUL; # uj modul kezdete $masodik = 1; # $MODUL::masodik $elso = 1; # $MODUL::elso $main::elso = 2;# $main::elsoA fõmodul neveihez még a $::elso hivatkozással is hozzáférhetünk. SzimbólumtáblaA modulok szimbólumtáblái futás közben elérhetõek, sõt módosíthatóak!!!A modulhoz a modul nevével megegyezõ szimbólumtábla tartozik, ami lényegében egy asszociatív tömb: %main::, avagy %MODULE::. Az itt lévõ bejegyzésekhez a *nev alakban is hozzáférhetünk. local(*main::alma) = *main::korte; local($main::{'alma'}) = $main::{'korte'};Ez a példa egy új álnév létrehozását mutatja. Ezek után minden korte-re alma-ként is hivatkozhatunk. Az egyetlen különbség az, hogy az elsõ fordítási idõben értékelõdik ki. Konstruktor, destruktorItt az awk programozók megint otthon érezhetik magukat. Ha a modulban BEGIN, illetve END kulcsszóval jelzett blokkot definiálunk, akkor azok a package használata elõtt, illetve után lefutnak.package hibakezeles; BEGIN { open(HIBAK,">./hibak"); } END { close(HIBAK); } sub kezeles { local ($szoveg) = @_; print HIBAK $szoveg, "\n"; }A programban elindított BEGIN blokkokhoz képest fordított sorrendben fognak lefutni az END blokkok. Egy modulban lévõ nevekhez a use kulcsszóval férhetünk hozzá: use MODUL; use hibakezeles kezeles;A use használata ekvivalens a következõvel: BEGIN { require MODUL; import MODUL; }Modulokat implementáló file-okat az @INC által meghatározott könyvtárakban keresi a rendszer. A .pm, .pl és .ph kiterjesztéseket nem kell kiírni a filenevek után. Bonyolultabb struktúrákA gondok mindig a mutatókkal kezdõdnek, de ez itt még álnevekkel is kombinálódik...Perl 4-ben kicsit nehézkes volt a bonyolult adatstruktúrák kezelése, de most már vannak referenciák, így már mindazt a borzalmat el lehet követni, amit egy C programban csak el tudunk képzelni. Sõt még többet is, mert egy C programban nem lehetett a változóneveket menet közben manipulálni. Referencák létrehozásaAz ötös verziótól kezdve Perlben három fajta referenciát különböztetünk meg: "hard", "soft", és "szimbolikus" referenciákat.A soft referenciával egy már meglévõ változóra mutathatunk:
$scalarref = \$scalar; $arrayref = \@ARGV; $hashref = \%ENV; $coderef = \&handler; # Névtelen dolgokra is lehet hivatkozni: $arrayref = [1, 2, ['a', 'b', 'c']]; $hashref = { 'Ádám' => 'Éva', 'Clyde' => 'Bonnie', }; $coderef = sub { print "Nem nyert!\n"; }; Referenciák használataNagyon egyszerû egy referenciát használni: a programban egy változó neve helyére bárhova beírhatunk egy megfelelõ típusú referenciát tartalmazó változót.
$ketto = $$scalarref; print "A program neve:",$$arrayref[0],"\n"; print "HOME=",$$hashref{'HOME'}; &$coderef(1,2,3);Persze lehet mutatni mutatóra is: $refrefref = \\\"valami"; print $$$$refrefref; $ketto = ${$scalarref}; print "A program neve:",${$arrayref}[0],"\n"; print "HOME=",${$hashref}{'HOME'}; &{$coderef}(1,2,3);No persze a blokk lehet bonyolultabb is: &{ $inditas{$index} }(1,2,3); # megfelelõ eljárás indul $$hashref{"KEY"} = "VALUE"; # 1. eset ${$hashref}{"KEY"} = "VALUE"; # 2. eset ${$hashref{"KEY"}} = "VALUE"; # 3. eset ${$hashref->{"KEY"}} = "VALUE"; # 4. esetItt az 1. és 2., illetve a 3. és 4. eset egyenértékû. print "A program neve:",$arrayref->[0],"\n"; print "HOME=",$hashref->{'HOME'};Ennek balértéke bármilyen kifejezés lehet, amely egy referenciát ad vissza. Ez az operátor el is hagyható {} vagy [] zárójelek között (de tényleg csak közöttük!): $array[$x]->{"valami"}->[0] = "január"; $array[$x]{"valami"}[0] = "január";Ezzel el is jutottunk a többdimenziós C-beli tömbökhöz: $tomb[42][4][2] += 42;A kódrészre mutató hard referenciáknál fontos megjegyezni, hogy még az ugyanazzal az utasítással generált blokkok is teljesen független eljárásoknak számítanak, pl. a my kulcsszóval definiált változóik különbözõek: sub newprint { my $x = shift; return sub { my $y = shift; print "$x $y\n"; }; } $h = newprint("Hello"); $g = newprint("Papa"); . . . &$h("world"); &$g("mama"); Hello world Papa mama Szimbolikus referenciákHa a fent említett hivatkozásokban egy blokk nem egy változó referenciájával, hanem egy string-gel tér vissza, a nyelv akkor sem esik kétségbe. Szorgalmasan elkezdi böngészni a szimbólumtáblát, hátha talál egy ilyen bejegyzést:$nev = "ize"; $$nev = 1; # $ize ${$nev} = 2; # $ize ${$nev x 2} = 3;# $izeize $nev->[0] = 4; # $ize[0] &$nev(); # &ize() $modulom = "MAS" ${"${modulom}::$nev"} = 5; # $MAS::izeHa ez a szabadság nem tetszik nekünk, akkor megköthetjük kezünket a use strict; használatával. OOPLehet enélkül manapság nyelvet készíteni?Amit a Perl objektumokról tudni kell:
ObjektumAz objektum bármilyen referencia lehet, ami meg van áldva azzal a tudással, hogy hol jött létre:package ValamiUj; sub new { bless {} } # 1. verzió sub new { # kicsit bonyolultabban... my $self = {}; bless $self; $self->initialize(); return $self; }A referencia általában egy asszociatív tömb szokott lenni, amely aztán az objektum saját kis szimbólum táblájaként szolgál... OsztályAz osztály egy package. Nincs semmi különös jelölés arra, hogy ez egy osztály, sõt még az inicializáló eljárást sem kell new-nak hívni.Egy osztályban csak a metódusok öröklésére van támogatás az @ISA tömbön keresztül. Ez egy modul neveket tartalmazó tömb. Ha egy metódust nem található meg az aktuális package-ban, akkor az ebben a tömbben felsorolt modulok lesznek bejárva a hiányzó alprogramért. Ez egy mélységi keresés lesz. Ha itt sem talál semmit, és van egy AUTOLOAD nevû függvény, akkor megpróbálja ezzel elõszedetni a hiányzó eljárást. Ha ez a lehetõség sem járt sikerrel, akkor egy UNIVERSAL-nak nevezett modulban fog keresgélni a rendszer. Az @ISA tömb szépsége az, hogy menet közben is lehet módosítani, azaz menet közben megváltoztathatjuk egy osztály leszármazási fáját! MetódusSemmi különös jelölés nincsen rájuk, kivéve a destruktorokat.Alapvetõen kétfajta metódus van:
package ValamiUj; sub holvagyok { my ($neve) = @_; print "holvagyok: $neve\n"; }Ez a következõképpen hívható: ValamiUj->holvagyok(); package ValamiUj; sub new { my $self = {}; bless $self; $self->{elso} = 1; # ez {"elso"}-vel egyenlõ $self->{ize} = 42; return $self; } sub kiir { my $self = shift; my @keys = @_ ? @_ : sort(keys(%$self)); foreach $key (@keys) { print "\t$key => $self->{$key}\n"; } }És ennek hívása: use ValamiUj; $obj = ValamiUj::new(); $obj->kiir(); # C++ stílus kiir obj "elso"; # "print" stílus Ami hiányzik a nyelvbõl
ÖtletekItt csak néhány ötletet mondok el, amik eddigi programjaimban jól jöttek:
perldoc perl # avagy man perl # avagy netscape http://augusta.inf.elte.hu/langs/perl/perl.html
Ezt a dokumentumot Frohner Ákos írta. Kiegészítette Nagy Péter írása és saját tapasztalatai, és Larry Wall írásai alapján: Milus János.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||