A Perl programozási nyelv

Procedurális stílus

Láthatóság

Perlben alapértelmezés szerint minden változó globális (pontosabban egyik sem az de erről később, egyelőre tekintsük őket globálisnak), azaz mindenki látja, és tud is rá hivatkozni, tudja módosítani. Ez programozási szempontból se nem kényelmes, se nem biztonságos. Szerencsére Perlben van lehetőség ezt megkerülni.

Az egyik lehetőség erre a local használata. Ennek az operátornak a segítségével a változónkat lokálissá tehetjük, a legszűkebb bezáró blokkra, szubrutinra, eval blokkra, vagy filera nézve. Ez úgy történik, hogy a globális változó értéke lementődik egy temporális helyre, ahonnan a blokk elhagyása után másolódik vissza az eredeti érték. Ebből kifolyólag ha a blokkot még nem hagytuk el, csak kihívunk belőle, akkor a hívott eljárásban a lokális értéket fogjuk látni. A blokkban pedig nem lesz elérhető a változó globális értéke.

#!/usr/bin/perl -w # itt adunk értéket a $a változónak $a = 'outer'; # itt hívjuk meg az értéket kiíró metódust printa(); # majd egy külön blokkban felveszünk egy local $a változót { local $a = 'inner'; print "local: \$a=$a\n"; # és kiírjuk a $a értékét printa(); } # a blokkból kilépve ismét kiírjuk a $a értékét printa(); # ez az eljárás nem vesz át paramétereket, hanem a globális $a változót írja ki sub printa { print "\$a=$a\n"; }
Ennek a programnak az eredménye a következő lesz:
$a=outer local: $a=inner $a=inner $a=outer
Érezhetően ez nem az, amit igazán szeretnénk.

Ezzel szemben a my már sokkal közelebb van ahhoz, amit más programozási nyelvekben megszokhattunk. Egy my-jal deklarált változó, legyen az skalár, tömb vagy hash, csak az adott blokkban létezik, és a globális változókat is elérhetjük a package nevének megadásával.

#!/usr/bin/perl -w # itt adunk értéket a $a változónak $a = 'outer'; # itt hívjuk meg az értéket kiíró metódust printa(); # majd egy külön blokkban felveszünk egy my $a változót { my $a = 'inner'; # kiírjuk a lokális változót print "my: \$a=$a\n"; # elérhetjük a külső változót is print "main: \$a=$main::a\n"; # és kiírjuk a $a értékét printa(); } # a blokkból kilépve ismét kiírjuk a $a értékét printa(); # ez az eljárás nem vesz át paramétereket, hanem a külső $a változót írja ki sub printa { print "\$a=$a\n"; }
Ennek a programnak az eredménye a következő lesz:
$a=outer my: $a=inner main: $a=outer $a=outer $a=outer
Ha egyszerre több változót is szeretnénk my kulcsszóval deklarálni, akkor azt úgy tehetjük meg, ha zárójellel vesszük körül, és ezzel tömb környezetbe helyezzük:
sub mysub { my ($a, $b) = @_; .... }
Itt most átvettünk két paramétert, deklaráltunk hozzájuk két lokálisan létező változót, ami megszunik, mikor kilépünk a szubrutinból.

Input, Output

Fileműveletekhez a Perl filehandle-t használ, ami nem valódi Perl változó, ezért ha hivatkozni akarunk rá, akkor az úgynevezett typeglob operátort kell használnunk (*). Erre akkor van szükségünk, ha a filehandle-t át szeretnénk adni, vagy el szeretnénk tárolni, vagy éppen csak át szeretnénk irányítani. Egy file kezelése röviden a következő módon történhet:
# myfile nevű file megnyitása, és hibakezelés, ha nem sikerül open(MYFILE, "myfile") or die "Can't open file: $!\n"; while ( $line = <MYFILE> ) { # sor olvasása a $line változóba print "olvastam: $line"; # a sor kiírása a STDOUT-ra } close MYFILE;
Ha egyszerűen csak a file tartalmát ki szeretnénk listázni:

open(FILE, "kiirni.txt") or die "A file-t nem tudom megnyitni.\n";
while (<FILE>) {
print;
}
close(FILE);

Ha egy sorba szeretnénk kiíratni a file tartalmát:

open(FILE, "kiirni.txt") or die "A file-t nem tudom megnyitni.\n";
while (<FILE>) {
chomp;
print;
}
close(FILE);

A megnyitott fileokat a Perl automatikusan lezárja. Ennek ellenére azért mindenképpen hasznos ha mi magunk is lezárjuk a filet, ezzel is jelezve, hogy már nem kívánunk olvasni belőle.
Érdekes és hasznos, hogy a <> operátor lista környezetben nem egy sort ad vissza, hanem minden sort beolvas a fileból, és sorok listáját kapjuk, amit aztán nyugodtan eltehetünk egy tömb változóba. A következő példa teljesen ekvivalens az előzővel, de itt a <> operátort lista környezetben használjuk.
# myfile nevű file megnyitása, és hibakezelés, ha nem sikerül open(MYFILE, "myfile") or die "Can't open file: $!\n"; print map "olvastam: $_", <MYFILE>; close MYFILE;

Megformázott output a printf segítségével

Könnyebb a megjelenítendő szöveget formázni mint a print-el. Két argumentuma van, az első a formázást vezérlő string a második pedig a szövegstring vagy szövegstringek listája.

Adattípus ----->Jelentés
c ------------->Karakter
d ------------->Tízes számrendszerbeli szám
e ------------->Exponenciális lebegőpontos szám
f ------------->Fixpontos lebegőpontos szám
g ------------->Kompakt lebegőpontos szám
ld ------------->Hosszú decimális szám
lo ------------->Hosszú nyolcas számrendszerbeli szám
lu ------------->Hosszú előjel nélküli decimális szám
lx ------------->Hosszú tizenhatos számrendszerbeli szám
o ------------->Nyolcas számrendszerbeli szám
s ------------->string
u ------------->Előjel nélküli decimális szám
x ------------->Tizenhatos számrendszerbeli szám
X ------------->Tizenhatos számrendszerbeli szám nagybetűkkel

A formázást vezérlő stringen belül mezőjelek vannak, amelyek meghatározzák a megjelenítendő adatok típusát és a mezőméretet, amelybe az adat kerüljön. A mezőjel % jel.

printf "%10s", "Hello"; #Kiírja a "Hello" stringet 10-hosszú mezőbe jobbra rendezve, vagyis a string a 6. pozíción kezdődik.
printf"%10d", 1000 #Kiírja az 1000 számot 10-hosszú mezőbe, jobbra rendezve.
$pi=3.14159; #Második argumentum egy változó. Ennek eredménye 3.14 lesz amelyet egy 5-hosszúságú mezőben jelenít meg, vagyis a
printf"%5.2f", $pi; #szám eggyel jobbralesz léptetve.
printf "10%s %5d %5.2f\n", "Hello", 123, $pi #Több string kiírása egyszerre

# myfile nevű file megnyitása írásra, és hibakezelés, ha nem sikerül open(MYFILE, ">myfile") or die "Can't open file: $!\n"; print MYFILE "Ez belemegy a fileba."; close MYFILE;

Fájl input, output

<"filenév" Olvasásra nyitja meg a fájlt >"filenév" Outputra nyitja meg a fájlt >>"filenév" Egy létező fájl végéhez ír adatot +<"filenév" írás és olvasásra nyitottuk meg a fájlt File nyitáskor fellépő hibák kezelése: ž warn kiírja hibát STDERR-re de engedi tovább futni a programot ž die kiírja hibát STDERR-re és leállítja a program futását. open(FILE, "myfile") or warn "can't open file"\n; open(FILE, "myfile") or die "can't open file"\n;

A warnt-t akkor érdemes használni ha lekezeltük a programunkban azt az esetet ha nem sikerül a fájlt megnyitni, vagyis a programnak két variációja van! Azt is megtehetjük, hogy egyik hibakezelő függvényt sem használjuk, ilyenkor a Perl undef-et ad vissza. Ha elhagyjuk a fenti példában az új sor karaktert, meg tudjuk nézni hová teszi a Perl a hibaüzenetet.
Vannak előre definiált filehandle-k: STDIN, STDOUT, STDERR. A typeglob operátor használatára példa a következő, amiben a STDOUT filehandle-t irányítjuk át egy fileba:
open(FILE, ">/tmp/a"); *STDOUT=*FILE; print STDOUT "hello"; # ez már a fent nevezett fileba megy
A fileok kezelése megoldható ezekkel a handle-ekkel, de van objektum-orientált interfész is, ami elrejti ezeket a handle-eket, és egy könnyen kezelhető, rugalmas interfészt ad. Az egyik az IO::File, a másik a FileHandle osztály. Ezek bemutatására most nincs idő, de ez előző 'olvastam' példa FileHandle-t használó, szinte olvashatatlanul tömör változatát ínyenceknek leírom:
use FileHandle; -r "myfile" ? print map "olvastam: $_", FileHandle->new("myfile")->getlines() : die "Can't read file: $!\n";
Természetesen bináris file-ok kezelésére is van mód. Egy filehandle-re kell meghívni a binmode függvényt, majd a read függvénnyel olvashatunk belőle, megadott pufferrel, megadott számú byteot. Bináris file-ba a syswrite utasítással írhatunk.
open(ORIG, "original"); open(COPY, ">copy"); binmode(ORIG); binmode(COPY); while (read(ORIG, $buffer, 1024)) { syswrite(COPY, $buffer); } close(COPY); close(ORIG);

Fájlvizsgálatok

Annak érdekében, hogy elkerüljük egy egész adatfájl felülírására, Perlben meg tudjuk nézni, hogy a fájlt, amit ki szeretnénk nyitni létezik e már vagy sem. Ezen kívül több mint 20 fájlvizsgálati lehetőség van. Most itt a leghasznosabbakat fogom felsőrolni. Minden fájlvizsgálatot egy gondolatjelet követő betű ír le majd ezt a fájl neve követi. Érthetően a betű a mutatja a fordítónak melyik vizsgálatot hajtson végre.

-e "myfile" #A myfile nevű fájl létezését ellenőrzi, visszatérési értéke igaz ha a fájl létezik, különben hamis. $file = "myfile" #Egy fájl írható és/vagy olvasható e if(-r/w $file){ open(FILE,"myfile"); } $file = "perl.exe"; #Egy fájl végrehajtható e if(-x $file){ print"Ez a file végrehajtható. \n"; }
Vizsgálat Eredmény -r A fájl olvasható -w A fájl írható -x A fájl végrehajtható -o A fájt a felhasználó birtokolja -R A fájl valódi felhasználó által olvasható -W A fájl valódi felhasználó által írható -X A fájl valódi felhasználó által végrehajtható -O A fájlt valódi felhasználó birtokolja -e A fájl létezik -z A fájl létezik, de a mérete 0 -s A fájl létezik, de a mérete NEM 0 -f A fájl sima fájl -d A fájl egy könyvtár -l A fájl egy symlink -S A fájl egy foglalat -p A fájl egy pipe -b A fájl egy blokkspeciális fájl -c A fájl egy karakterspeciális fájl -u A fájl setuid -g A fájl setgid -k A fájlnak ragadós bitkészlete van -t Isatty() a fájlkezelőre igaz -T A fájl egy szövegfájl -B A fájl egy bináris file -M Módosítás ideje napokban -A Hozzáférés ideje napokban -C Az I-csomópont módosítás ideje napokban

Mivel a fájlvizsgálatokkal csak egy-egy információt tudunk meg az egyes fájlokról, néha jól jön a "stat" függvény ami egy meghatározott fájlról az alábbi információval tér vissza:
Egy példaprogram filekezelésre:

A program a kiirni.txt file-t nyitja meg, ami tartalmazza a Biblia könyveinek egy részét. Ennek a tartalmát kiírja a képernyőre, majd a felhasználó kiegészítheti a listát annyi könyvvel, amennyivel akarja (0-val is lehet). Ezután újra kiírja a file aktuális tartalmát, majd megformázza kissé a szöveget: 1 Mozes helyett Mozes első konyve kerül kiírásra, Ruth helyett pedig Ruth konyve. Majd kereshetünk is a könyvek közt, amelyik nevét megadjuk, arról kiírja, hogy hanyadik könyve a Bibliának (feltéve, hogy szerepel már a listánkban).
print "\nA file jelenlegi tartalma:\n"; &kiir(); # meghívom a kiir függvényt, ami lejjebb található. open(FILE, ">>kiirni.txt") or die "A file-t nem tudom megnyitni.\n"; # Írásra nyitom meg a file-t, pontosabban a végéhez ír hozzá. # Ha nem tudja megnyitni, hibaüzenettel kilép print "\nA Biblia kovetkezo konyveinek a neve(amennyit szeretne <enter>-rel elvalasztva)!"; $book = <STDIN>; # standard bemenetről jön while ($book !~"^\n") { #Amíg nem üres sort üt be, addig megy a ciklus print FILE $book; # Beírjuk a file-ba a kapott stringet $book = <STDIN>; } close(FILE); print "\nMost a kovetkezo a file tartalma:\n"; &kiir(); print "\nSzebb formaban igy is irhato:\n"; open(FILE, "kiirni.txt") or die "A file-t nem tudom megnyitni.\n"; while (<FILE>) { chomp; # levágja a sorvége jelet a beolvasott stringről &szepit($_); # Meghívja a szepit függvényt a beolvasott stringgel } close(FILE); $book = "Mate"; print "\nMelyik konyvet szeretne megkeresni?(1Mozes, 2Mozes...vagy Mozes, Samuel... )\n"; $book = <STDIN>; $szamol=1; $van = "0"; open(FILE, "kiirni.txt") or die "A file-t nem tudom megnyitni.\n"; while (<FILE>) { if ($_ =~ /$book/) { # illeszti a beolvasott mintát print "A $szamol-dik konyv.\n"; $van = "1"; } $szamol+=1; } if ($van = '1') { goto Cimke;} #Ha volt találat, a Cimkére ugrik print "Nincs ilyen konyv!\n"; #Ha nem volt... Cimke: close(FILE); $book = <STDIN>; sub kiir { # A file tartalmának kiirása a képernyőre open(FILE, "kiirni.txt") or die "A file-t nem tudom megnyitni.\n"; while (<FILE>) { print; } close(FILE); } sub szepit { # pl az "1Mozes" kijavítása "Mozes első konyve"-re # "Ruth"-ot pedig "Ruth konyve"-vé alakitja $szo = $_; # Az átadott string if ($szo=~/\d/) { # ha illeszkedik rá szám, levágja, (biztos van rá egyszerűbb mód is): $mi = chop($szo); $vissza = undef; while ($szo =~ /\d/) { $vissza = $mi . $vissza ; $mi = chop($szo); } # Hozzárakja a számot betűvel hátul: if ($mi=~"1") { $vissza = $vissza . " első"; } if ($mi=~"2") { $vissza = $vissza . " masodik"; } if ($mi=~"3") { $vissza = $vissza . " harmadik"; } if ($mi=~"4") { $vissza = $vissza . " negyedik"; } if ($mi=~"5") { $vissza = $vissza . " otodik"; } } else { # Ha nem volt szám a string-ben, nem változtat rajta. $vissza = $szo; } $visza = $vissza . " konyve\n"; #hozzáfuzzük, hogy "konyve" print $vissza; }

Előre definiált változók

awk-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-szeru" 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:
$_, $ARG
Az alapértelmezett változó. Ha valahol nincs változó, akkor ott ez lesz használva.
$1,$2,$3...
Reguláris kifejezésekből kapott betűcsoportok.
$&, $MATCH
Legutolsó mintaillesztésnél az illesztett rész.
$`, $PREMATCH
Legutolsó mintaillesztésnél a $& előtti rész.
$', $POSTMATCH
Legutolsó mintaillesztésnél a $& utáni rész.
$., $NR
Utolsó olvasási műveletnél az olvasott sor sorszáma. (Ez csak olvasható változóként kezelendő!)
$/, $RS, $INPUT_RECORD_SEPARATOR
Input rekordok elválasztása. Ez alapesetben az újsor karakter, de bármire lecserélhető. Ha az üres stringet adjuk meg, akkor üres sorok lesznek a határok. Ez nem ugyanaz mint $/ = "\n\n";, mert a $/ = "\n\n"; több üres sort is egyetlen határnak tekint.
$|, $OUTPUT_AUTOFLUSH
Output bufferelését szünteti meg, ha az értéke nem egy.
$\, $ORS, $OUTPUT_RECORD_SEPARATOR
Az a karakter, amit a print ki fog írni minden sor végén. Ez alapesetben üres.
$?, $CHILD_ERROR
Utolsó gyermek process visszatérési értéke. Ez a wait() függvény visszatérési értéke, tehát a valódi exit() értéket ($? 8)-ként kaphatjuk meg.
$$, $PID, $PROCESS_ID
A process azonosító száma.
$<, $UID, $REAL_USER_ID
Valódi user azonosítója.
$>, $EUID, $EFFECTIVE_USER_ID
A futás közbeni jogok tulajdonosa. Ez az érték csak a setuid programoknál vált át a file tulajdonosának jogaira. 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 :-).
$(, $GID, $REAL_GROUP_ID
Valódi csoport azonosítója. Ha a rendszer több csoportot is támogat egyszerre, akkor ez egy listája azoknak a csoportoknak, amiben a process benne van.
$), $EGID, $EFFECTIVE_GROUP_ID
Effektív csoport azonosítója. Ez setgid program futtatásakor különbözhet az előzőtől.
$0, $PROGRAM_NAME
A programot indító parancs neve (egy Perl script-nél a script neve, nem a "perl" szó).
@ARGV
A parancssori argumentumok listája.
@INC
Azon könyvtárak listája, ahol a Perl elkezd keresgélni egy modul után.
%INC
A használt modulok tömbje (filenév,elérési-út) elemekkel.
%ENV
Környezeti változók tömbje, pl.:
print "Otthonom: ", $ENV{"HOME"}, "\n";
%SIG
Kivételkezelők tömbje.
sub handler { # az első paraméter a signal neve local($sig) = @_; print "Elkaptam $sig-t!\n"; exit(0); } $SIG{'INT'} = 'handler'; $SIG{'QUIT'} = 'handler'; ... $SIG{'INT'} = 'DEFAULT'; # alapértelmezett $SIG{'QUIT'} = 'IGNORE'; # figyelmen kívül hagy
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.

Beépített függvények

Ez 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...

bless REF,PACKAGE
A REF referenciát egy PACKAGE modulban leírt objektumként fogja kezelni. Lényegében ez az útja egy új objektum létrehozásának.
caller
Megmondja, hogy ki hívta az aktuális kódrészletet...
($package, $filename, $line) = caller;
chdir EXPR
A working directory beállítására ad lehetőséget. Ha paraméter nélkül hívjuk a home directory az alapértelmezett.
chomp
Az alant lévő chop függvény egy biztonságosabb verziója: csak a sorvége karaktert vágja le a kifejezés, lista vagy ezeknek hiányában a $/ végéről.
chop
Levágja az utolsó jelet a sor végéről. Ez sorok olvasása után hasznos.
while(<>) { chop; # $_ végéről vág ... } chop($cwd = `pwd`); # aktuális könyvtár
chr NUMBER
Visszaadja az adott ASCII kódú karaktert.
defined EXPR
Megmondja, hogy egy EXPR változó definiált-e.
delete EXPR
Egy elem törlése egy asszociatív tömbből, pl.: delete $tomb{"eleme"};
die LIST
Ez lényegében a C könyvtári exit() függvény, csak a LIST tartalmát még kiírja mielőtt kilép a programból.
dump LABEL
Egy core dump! Ha a core dump eredményeképpen kapott file-t futtatjuk, akkor az a LABEL cimkénél fog elindulni. Régebben ez volt a módja egy Perl program "fordításának", manapság már nem javasolják.
each ASSOC_ARRAY
Egy asszociatív tömb elemeit iterálja:
while(($key,$value) = each %ENV) { print "$key=$value\n"; }
környezeti változók kiírása (ld. még a változókat)
eof FILEHANDLE
Igazat ad ha a következő olvasás a FILEHANDLE által azonosított fájlon eof-al térne vissza. Paraméter nélkül az utolsó olvasás eof-státuszát kapjuk.
eval BLOCK
A BLOCK futtatása az aktuális környezetben. A BLOCK egy string is lehet. Figyelem: az eval {...}; forma egyszerű utasításnak számít, ezért utána ki kell rakni a ';'-t!
exec LIST
Egy operációs rendszer parancsot hívhatunk meg vele. A Perl script futása felfüggesztődik amíg a másik program nem terminál. A LIST elemei a futtatandó program és a paraméterek.
exists EXPR
Megmondja, hogy létezik-e az asszociatív tömb egy eleme, pl.: if exists $tomb{"eleme"} ...
exit EXPR
Azonnal kilép a programból az EXPR kifejezés értékével.
format
Deklarál egy nyomtatási képformátumot, amit a write függvény használ fel.
format Something = Test: @<<<<<<<< @||||| @ $str, $%, '$' . int($num) $str = "widget"; $num = $cost / $quantity; $~ = 'Something'; write;

Ezen kívül még amit a formátumról érdemes tudni, kicsit bővebben:
A formátum a Perl által biztosított jelentéskészítő sablon. Ez a sablon egy állandó (oszlopok fejlécei, címkék, rögzített szöveg, stb.) és egy változó (az éppen kimutatandó adatok) részt (mezők) definiál. Használata három részből áll: formátum definiálása, a kiírandó adatok betöltése a formátum mezőkbe, formátum behívása.
A formátum definíció bárhol előfordulhat a szövegben, mint egy szubrutin.
A mezősorok rögzített szövegeket és a változó szöveg számára mezőtartókat tartalmazhatnak; a rákövetkező sorban adhatjuk meg, mely értékeket kívánjuk megjeleníteni a mezőtartókban. A mezőtartókat @<<...<alakban adhatjuk meg, n széles mezőtartóhoz n-1 < jelet biztosítva. Ez a forma balra igazított; a jobbra igazítást a @-ot követő > jelekkel biztosíthatjuk.
A formátumot a write (formátum_név) függvénnyel hívhatjuk be.
Numerikus mezőtartókat pl. @###.## alakban definiálhatunk; a tizedes pont opcionális.
Több soros mezőtartók jele @*, az ezután következő változóban tárolt szöveg így tartalmazhat \n újsor karaktert is.
Kitöltött mezőt például ^<<< alakban állíthatunk elő. Ezek lényege, hogy segítségükkel kitöltött bekezdéseket hozhatunk létre, alkalmas sorokba tördelve a szóhatárokon, ha szükséges, sorátvitellel. A kitöltött mező értéke skaláris változó, melyet a mezőbe való betöltéskor a Perl megváltoztat: a változó értéke a mező kitöltése után az, ami megmaradt a betöltött szavak eltávolítása után. Így a követjező formátummal:

format formátum
^<<<<<<<<<<<<<<<<<<<
$változó
^<<<<<<<<<<<<<<<<<<<
$változó
^<<<<<<<<<<<<<<<<<<<
$változó
^<<<<<<<<<<<<<<<<<<<
$változó
^<<<<<<<<<<<<<<<<<<<
$változó

a $változóban tárolt szöveget 5 darab, 20 karakter hosszú sorba tördelve írathatjuk ki. Arra az esetre, ha a megadott mezősorok nem lennének elegendők egy változóban tárolt szöveg kiírására, két egymást követő ~ (tilde) jelet írhatunk a meződefinícióba. Az ilyen sorokat a Perl automatikusan addig ismétli, míg az eredmény egy teljesen üres sor nem lesz; az üres sor elnyomódik. A sor megállásához természetesen az is szükséges, hogy ne legyen benne állandó szöveg, különben sohasem lesz üres.
A lap teteje formátum: a Perl lehetővé teszi oldalak formázását és a nyomtatón megjelenő oldalak számozását.
Ez utóbbit a Perlben előre definiált $% változó biztosítja.
A következő formátum-definíció megakadályozza például, hogy a címkék széttörjenek az oldalhatárokon megszámozza az oldalakat:

format CIMKE_TETEJE =
@< oldal
$%

Az alapértelmezett oldalhossz 60 sor, mely az összes Perlben lévő alapértelmezéshez hasonlóan a select(fájlkezelő) utasítással az STDOUT helyett másik fájlkezelőt választunk ki.

getc FILEHANDLE
Egy bájtot olvas a FILEHANDLE által specifikált fájlból. Ha paraméter nélkül hívjuk akkor az STDIN-ről teszi ugyanezt.
glob EXPR
EXPR file-név teljesen kiterjesztve. Úgy működik, mint a shell-ek file-név kiterjesztő algoritmusa:foreach $file (glob "*.pl") {...}
index STR , SUBSTR [, POSITION]
SUBSTR előfordulását keresi STR-ben POSITION helyen kezdve.
join EXPR, LIST
A LIST által felsőrolt stringeket összekapcsolja egy stringgé az EXPR szeparátort felhasználva.
keys ASSOC_ARRAY
ASSOC_ARRAY kulcsait adja vissza egy tömbben.
last
A C-beli break-hez hasonló, kilép az aktuális ciklusból. A program a ciklus utáni utasításon folytatódik. A continue blokk nem hajtódik végre. Ha egy cimkét írunk mögé a cimkére ugrik vissza.
$i = 7; CIKLUS: while (1) { $j = 1; while (1) { last if $j == 3 && $i < 9; last CIKLUS if $j == 3; print $i, $j++, ":"; } $i++; }
és az eredmény: 71:72:81:82:91:92
local EXPR
EXPR-ben felsőrolt változók a blokkra nézve lokálisak lesznek. Ez a dinamikus láthatóság. Használatakor az interpreter egy verembe menti az azonos nevű globális változót, majd a blokk végén visszatölti.
my EXPR
EXPR-ben lévő változók csak az aktuális blokk-ban lesznek láthatóak. A local-tól eltérően ez fordítási időben értékelődik ki, tehát a változónevekben nem lehetnek mágikus karakterek. Az így definiált változók inkább a C nyelv statikus lokális változóihoz állnak közel, mert a külvilág számára teljesen láthatatlanok lesznek, illetve rekurzió esetén is csak egyszer jönnek létre, két hívás között pedig megőrzik az értéküket.
sub kiir { my ($szoveg1, $szoveg2) = @_; chomp $szoveg1; chomp $szoveg2; print $szoveg1, ':', $szoveg2, '\n\n'; }
next
A C-beli continue szinonímája: a következő iterációra lép egy ciklusban.
open FILEHANDLE, EXPR
EXPR-ben leírt file megnyitása a FILEHANDLE leíróba.
open(FILE, "valami.txt"); # írás-olvasás open(BE, "</etc/passwd"); # csak olvasás open(KI, ">/tmp/output"); # csak írás open(FINGER,"finger @augusta |"); # olvasás pipe-ból open(RENDEZ,"| sort /tmp/ki"); # írás pipe-ba
Az í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" kiírása a FILE-ba $sor = <BE> # sor olvasása
pack MINTA,LIST
A LIST tartalmát a MINTA szerint binárisan összepakolja. Főleg külső eljárások hívása előtt kell megtenni.
pos SCALAR
Azt a pozíciót adja meg, ahol a legutolsó m//g keresés megállt a SCALAR változóhoz. Érték is adható ennek a függvénynek, amelynek hatására a következő keresés annál a karakternél fog folytatódni, amelyet megadtunk.
# 11111 # 012345678901234 # | | | | $s = 'bbb abbbabb bbb'; while ($s =~ m/bb/g) { print pos($s), "\n"; } kimenete: 2 7 11 14 és # 111111 # 0123456789012345 # || || | || $s = 'bbb abbbabb bbb'; while ($s =~ m/bb/g) { print $i = pos($s), "\n"; pos($s) = --$i; } amelynek kimenete: 2 3 7 8 11 14 15
pop ARRAY
Kiveszi egy tömb utiolsó elemét és visszatérési értékként adja.
push ARRAY,LIST
Az ARRAY tömböt, mint egy vermet kezeli, és a LIST lista elemeit hozzáfuzi a tömb végéhez. Ennek megfelelően növekszik a tömb mérete. A visszatérési érték a tömb új mérete. Ugyanaz mint a
for $value (@LIST) { $ARRAY[++$#ARRAY] = $value; }
utasítás, csak hatékonyabb.
print FILEHANDLE LIST
Kiírás általános utasítása. A FILEHANDLE elhagyható, ekkor a standard kimenetre ír ki. A FILEHANDLE és a LIST között nem lehet vessző!
reset EXPR
Törli az összes változót, amelynek neve az EXPR-re (?PATTERN?) módon illeszkedik.
reset 'a-z'; # Törli az összes kisbetűs változót reset 'A-Z'; # Ezzel vigyázzunk mert az ARGV, INC, ENV # és SIG tömbjeink is áldozatul esnek neki
return
Alprogramból érték visszaadása. Ha ez nem szerepel, akkor az alprogram utolsó utasításának értéke lesz visszaadva.
ref EXPR
Visszatérési értéke TRUE, ha az EXPR egy referencia és FALSE egyébként. Az érték, amelyet visszaad attól függ, hogy mi az az objektum amelyre a referencia vonatkozik. A beépített típusok: REF, SCALAR, ARRAY, HASH, CODE, GLOB. Ha a hivatkozott objektum egy osztályhoz tartozik ,akkor az osztály nevét adja meg. A ref hasonló a C-beli a typeof operátorhoz.
if (ref($r) eq "HASH") { print "r is a reference to an associative array.\n"; } if (!ref ($r) { print "r is not a reference at all.\n"; }
shift LIST
A LIST tömböt elmozdítja egy elemmel lefele. Az első elemmel tér vissza, és az törlődik is abból.
sleep EXPR
A script nyugovóra tér az EXPR-ben megadott másodpercre.
sort LIST, vagy sort SUBNAME LIST
LIST rendezése lexikografikusan, vagy a SUBNAME-ben definiált alprogramnak megfelelően. A SUBNAME alprogramnak egy érvényes összehasonlításnak kell lenni.
splice ARRAY,OFFSET
Kiveszi az OFFSET és LENGTH paraméterek által meghatározott részét az ARRAY tömbnek, és helyette berakja a LIST lista elemeit, ha meg van adva lista. Visszatérési értéke a kivett elemek listája. A tömb csökken vagy nő, ahogy szükséges. Ha LENGTH nincs megadva, akkor az OFFSET értéktől kezdődően mindent kivesz. A következő utasítások azonosak, (feltételezzük hogy $[ értéke nulla):
push(@a,$x,$y) splice(@a,$#a+1,0,$x,$y) pop(@a) splice(@a,-1) shift(@a) splice(@a,0,1) unshift(@a,$x,$y) splice(@a,0,0,$x,$y) $a[$x] = $y splice(@a,$x,1,$y)
sprintf FORMAT, LIST
A printf-ben megszokottak szerint illeszti be a FORMAT-ban megadott stringbe a LIST változóinak értékét.
stat EXPR
Egy 13 elemu tömböt ad vissza, amely a fájl státuszát adja meg. A fájl vagy meg van nyitva és a FILEHANDLE fájlkezelőhöz rendelve, vagy EXPRESSION adja meg a nevét. Hiba esetén nulla listát ad vissza. Tipikus felhasználás:
($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
Nem minden mező támogatott minden fájlrendszerben. Az egyes mezők értelme:
  • dev: az eszköz száma
  • ino: inode száma
  • mode: fájlmód, típus és engedélyek
  • nlink: a hard linkeke száma a fájlhoz
  • uid: a fájl tulajdonosának numerikus azonosítója
  • gid: a fájlt tulajdonosának numerikus csoport azonosítója
  • rdev: eszközazonosító (speciális fájloknál)
  • size: a fájl teljes mérete bájtokban
  • atime: a fájl utolsó hozzáférési időpontja
  • mtime: a fájl utolsó módosítási id?pontja
  • ctime: az indode változásának ideje
  • blksize: preferált blokk méret
  • blocks: a pillanatnyilag lefoglalt blokkok száma

(Az időpontok 1970. január 1 0:00 GMT óta eltelt másodpercekben vannak megadva.) Ha a stat-nak egy speciális fájlnevet, az aláhúzás karaktert adjuk meg akkor nem hívja meg a rendszerfüggvényt, hanem a legutolsó fájltesztelés, vagy stat eredményeit használja.
study SCALAR
Az adott változó tartalmát tanulmányozza egy kicsit, hogy később több mintaillesztést hatékonyabban végezhessünk el rajta. Ez tényleg csak akkor jó, ha több mintaillesztést használunk ugyanarra a változóra!
tie VARIABLE,PACKAGENAME,LIST
Az adott változót hozzárendeli a PACKAGENAME-ben leírt struktúrához. Ezzel lehet egy egyszerű asszociatív tömbhöz hozzárendelni egy adatbázist, ahol a tömb indexei lényegében keresési kulcsok lesznek. A PACKAGENAME modulban a változó típusától függően különböző függvényeket kell megírni:
  • asszociatív tömb
    • TIEHASH objectname, LIST
    • DESTROY this
    • FETCH this, key
    • STORE this, key, value
    • DELETE this, key
    • EXISTS this, key
    • FIRSTKEY this, key
    • NEXTKEY this, key
  • tömb
    • TIEARRAY objectname, LIST
    • DESTROY this
    • FETCH this, key
    • STORE this, key, value
  • skalár
    • TIESCALAR objectname, LIST
    • DESTROY this
    • FETCH this
    • STORE this, value
undef EXPR
EXPR változó megszüntetése
untie VARIABLE
Egy tie kapcsolat megszüntetése.
unpack
pack függvény ellenkezője
use MODULE, LIST
MODULE modul LIST-ben felsőrolt nevei láthatóvá válnak az aktuális package-ban. Ha a LIST elmarad, akkor a MODULE által exportált változók válnak láthatóvá. A no kulcsszó a use ellentettje, azaz a láthatóságot megszünteti.
wantarray
Igaz lesz az értéke, ha a végrehajtás alatt álló alprogram visszatérési értékét egy listához akarjuk rendelni. Ezzel a függvényhívással az alprogram lényegében meg tudja nézni, hogy milyen környezetben hívták meg őt, és ettől függően akár más-más típusú visszatérési értéke is lehet!
warn LIST
Mint a die, csak nem lép ki a programból.

Alprogramok

awk-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-szeru" 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:
$_, $ARG
Az alapértelmezett változó. Ha valahol nincs változó, akkor ott ez lesz használva.
$1,$2,$3...
Reguláris kifejezésekből kapott betűcsoportok.
$&, $MATCH
Legutolsó mintaillesztésnél az illesztett rész.
$`, $PREMATCH
Legutolsó mintaillesztésnél a $& előtti rész.
$', $POSTMATCH
Legutolsó mintaillesztésnél a $& utáni rész.
$., $NR
Utolsó olvasási műveletnél az olvasott sor sorszáma. (Ez csak olvasható változóként kezelendő!)
$/, $RS, $INPUT_RECORD_SEPARATOR
Input rekordok elválasztása. Ez alapesetben az újsor karakter, de bármire lecserélhető. Ha az üres stringet adjuk meg, akkor üres sorok lesznek a határok. Ez nem ugyanaz mint $/ = "\n\n";, mert a $/ = "\n\n"; több üres sort is egyetlen határnak tekint.
$|, $OUTPUT_AUTOFLUSH
Output bufferelését szünteti meg, ha az értéke nem egy.
$\, $ORS, $OUTPUT_RECORD_SEPARATOR
Az a karakter, amit a print ki fog írni minden sor végén. Ez alapesetben üres.
$?, $CHILD_ERROR
Utolsó gyermek process visszatérési értéke. Ez a wait() függvény visszatérési értéke, tehát a valódi exit() értéket ($? 8)-ként kaphatjuk meg.
$$, $PID, $PROCESS_ID
A process azonosító száma.
$<, $UID, $REAL_USER_ID
Valódi user azonosítója.
$>, $EUID, $EFFECTIVE_USER_ID
A futás közbeni jogok tulajdonosa. Ez az érték csak a setuid programoknál vált át a file tulajdonosának jogaira. 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 :-).
$(, $GID, $REAL_GROUP_ID
Valódi csoport azonosítója. Ha a rendszer több csoportot is támogat egyszerre, akkor ez egy listája azoknak a csoportoknak, amiben a process benne van.
$), $EGID, $EFFECTIVE_GROUP_ID
Effektív csoport azonosítója. Ez setgid program futtatásakor különbözhet az előzőtől.
$0, $PROGRAM_NAME
A programot indító parancs neve (egy Perl script-nél a script neve, nem a "perl" szó).
@ARGV
A parancssori argumentumok listája.
@INC
Azon könyvtárak listája, ahol a Perl elkezd keresgélni egy modul után.
%INC
A használt modulok tömbje (filenév,elérési-út) elemekkel.
%ENV
Környezeti változók tömbje, pl.:
print "Otthonom: ", $ENV{"HOME"}, "\n";
%SIG
Kivételkezelők tömbje.
sub handler { # az első paraméter a signal neve local($sig) = @_; print "Elkaptam $sig-t!\n"; exit(0); } $SIG{'INT'} = 'handler'; $SIG{'QUIT'} = 'handler'; ... $SIG{'INT'} = 'DEFAULT'; # alapértelmezett $SIG{'QUIT'} = 'IGNORE'; # figyelmen kívül hagy
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ása

Alprogramok deklarálása:

sub NEV; # a NEV ismertté tétele sub NEV(PROTO); # u.a. de prototípussal sub NEV BLOCK # deklarálás és definíció sub NEV(PROTO) BLOCK # u.a. prototípussal
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. A visszatérési érték az alprogram utolsónak kiértékelt kifejezésének értéke lesz, hacsak nincs egy return utasításban más megadva.
sub max { my $max = pop(@_); foreach $elem (@_) { $max = $elem if $max < $elem; } $max; }
Az alprogram deklarálásakor megadhatunk prototípust is. A prototípus nem más, mint a $, @, és % karakterek sorozata, ami megmondja, milyen típusú paramétereket vár a függvény. A @ és a % karakterek csak a sorozat végén szerepelhetnek, mert tömb (ill. hash) átvétele az összes fennmaradó paramétert lenyeli, tehát az utána felsőrolt változók sohasem kapnának értéket.
sub max($$) { ... } $c = max($a, $b); # ez jó @l = ($a, $b); $c = max(@l); # itt hibát kapunk $c = &max(@l); # így viszont lehet
A prototípust ritkán adjuk meg, mert nagyon sokszor kényelmes egy két skalárt váró függvényt egy kételemu listával hívni (mint az előbb próbáltuk). A prototípus ellenőrzése kikerülhető, ha a függvényt & karakterrel vagy indirekt módon (pl. referencián keresztül) hívjuk.

Lokális változók alprogramokban:

Két utasítás létezik lokális változók definiálására: Amikor az alprogram véget ér, lokális változói megsemmisülnek; ha ismét meghívásra kerül, a lokális változókból új másolatok definiálódnak.

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ált
Alprogram 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;

Paraméterátadás:

Érték szerint:

Alprogramoknak értékeket adhatunk át, melyeket argumentumoknak nevezünk. Ezek száma tetszőleges lehet, de közülük csak egy lehet lista, mert az értékek egy egyszerű listába kerülnek. Ha listát adunk át, akkor annak az utolsó argumentumnak kell lennie.
sub ketlista{ my (@lista1, @lista2) = @_; # lista2 mindig ures } # @_ elemei lista1-be kerulnek
Az argumentumok egy listája konvertálódnak, mely egy speciális rendszerváltozónak, a @_-nak adódik értékül. Minden egyes alprogram argumentum-listájához létezik a @_-ból egy példány (a @_ egy lokális változó).

Név szerint:

Alprogramnak egy tömbváltozót név szerint is átadhatunk definiálva a változónévhez egy álnevet (alias).
&my_sub{ my (@subarray) = @_; $arraylength = @subarray; }
A my_sub meghívásakor @array változóban tárolt lista a @_ változóba másolódik. A másolás nagy méretu tömbök esetén időigényes lehet.
&my_sub{ my (*subarray) = @_; $arraylength = @subarray; }
A *subarray definíció mondja meg a Perl interpreternek, hogy az a my_sub-nak átadott aktuális listával dolgozzon ahelyett, hogy másolatot készítene.

Ezt az alprogramot a @ helyett a *-gal kezdődő tömbváltozónévvel hívjuk meg:

@myarray = (1, 2, 3, 4, 5); &my_sub(*myarray);
Az alprogram végrehajtása alatt a @subarray név azonos a @myarray névvel.
Ügyeljünk arra, hogy a my_sub-ban a @subarray tartalmának változtatásakor a @myarray tartalma is változik.

Cím szerint:

A C-hez hasonlóan ekkor az átadott érték valamely objektumnak a címe, nem pedig az értéke. A referencia felhasználásával indirekt módon tudjuk az objektum értékét megváltoztatni.
Példa: #!/usr/bin/perl @var1 = 1; @var2 = 2; sub my_sub{ my ($a, $b) = @_; $$a++; $$b++; } &my_sub2(\$var1, \$var2); print ("\$var1=$var1 \$var2=$var2\n"); #Az output: $var1=2 $var2=3
Példa: sub.pl

Predefiniált alprogramok:

A Perl definiál három speciális alprogramot, melyek speciális időben kerülnek végrehajtásra.

Névtelen alprogram létrehozása:

$alpref = sub BLOCK; # deklarálás &$alpref(1, 2, 3); # hívás
Ez a technika főleg egyszer használatos alprogramoknál lehet hasznos, például egy signal kezelő átdefiniálásakor.

Névtelen alprogramok definiált környezete

A névtelen alprogramokra jellemző, hogy mindig abban a környezetben futnak, amelyben definiálták őket, még akkor is, amikor az adott környezeten kívülről kerülnek meghívásra. Ez egy érdekes módja lehet a paraméterátadásnak, és callback jellegu kódrészeket lehet vele írni.
sub newprint { my $x = shift; return sub { my $y = shift; print "$x, $y!\n"; }; } $h = newprint("Hello"); $g = newprint("Üdvözlet"); # Valamivel később... $h("világ!"); $g("mindenkinek");
És az eredmény:
Hello, világ! Üdvözlet, mindenkinek!

Beépített függvények átlapolása

Sok beépített függvény átlapolható, de ezt csak akkor érdemes kipróbálni, ha jó okunk van rá. Ilyen eset lehet a nem Unix-rendszereken a környezet emulálása. Az átlapolás a subs pragma segítségével történhet, például így:
use subs 'chdir'; # az átlapolandó beépített függvények chdir $valahova; # az új chdir használata sub chdir { ... } # a chdir megvalósítása

Kiértékelési környezetek

Minden utasítás, operátor kiértékelése Perlben egy bizonyos környezetben (kontextusban) hajtódik végre. Ezek két fő fajtája a skalár és a lista környezet. Attól függően, hogy épp melyikben vagyunk, a kifejezések különbözőképpen értékelődhetnek ki.
Például egy lista ha lista környezetben van, akkor visszaadja minden elemét. Ha viszont skalár környezetben van, akkor a tömb elemszámát adja vissza. Mi történik, ha a következőt írjuk le?
@empty; unless (@empty) { ... } unless (()) { ... }
@empty egy üres tömb, ennek az elemszáma 0, amiből '0' lesz, ami pedig definíció szerint hamis. A második esetben azonban nem pontosan erről van szó. Ha ugyanis nem változóban érjük el a listát, hanem a , operátorral (illetve itt ()-val) hozzuk létre, akkor a lista skalár környezetben az utolsó elemét adja vissza. Ez ennél az üres listánál történetesen undef-et ad (ami nem azt jelenti, hogy undef az utolsó eleme, mert akkor már nem lenne üres!), ami aztán ''-gé konvertálódik, ami pedig hamis lesz.
Néhány további rövid példa:
$val = ('a', 'b', 'c'); # $val == 'c' @val = (@list1, @list2); # listák kiegyenesítése @val = 3; # @val tartalmazni fogja a skalárt ($a, $b, $c) = @list; # szétosztja a lista elemeit a skalárok között, # a maradékot pedig eldobja
A wantarray függvénnyel mi magunk is megtudhatjuk, hogy egy eljáráson belül milyen környezetben vagyunk: lista-e vagy skalár. A következő példa ennek felhasználására mutat egy példát (a példa alapja a perldoc -f wantarray oldalon felhozott példa):
sub wantarray_test { # ha void contextben vagyunk, akkor nincs értelme sokat dolgozni return unless defined wantarray; # valamilyen nagy műveletigényu számítás elvégzése # ez le sem fut, ha void contextben vagyunk, azaz ha nem használnánk # fel az eredményt my @a = complex_calculation(); if ( wantarray ) { # ha lista környezetben vagyunk, akkor adjuk vissza a listát return @a; } else { # skalár környezetben az elemeket :-val összefuzve adjuk vissza return join(':', @a); } }
Lista környezetben erőltethetünk skalár környezetet a scalar kulcsszóval. Például a következő példa a listák elemszámainak listáját állítja elő.
@counts = (scalar @list1, scalar @list2);
Ha itt kihagynánk a scalar kulcsszókat, akkor a listák lista környezetben értékelődnének ki, és a tartalmukat adnák vissza, ami aztán kiegyenesítve másolódna az @counts listába.

Modulok

Ja kérem, ez egy "komoly" nyelv!

package

A 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).

$első = 1; # ez a $main::első package MODUL; # uj modul kezdete $masodik = 1; # $MODUL::masodik $első = 1; # $MODUL::első $main::első = 2; # $main::első
A főmodul neveihez még a $::első hivatkozással is hozzáférhetünk.
Perlben kifejezhetjük, hogy nincs adott aktuális package. Ehhez adjuk meg a package utasítást packagenév nélkül.
package;
Ekkor az összes változó csak packagenév minősítéssel használható.
$MODUL::masodik = 21; # OK $masodik = 21; # hiba - nincs aktuális package
E megszorítás érvényben marad addig, amíg nem definiálunk explicit egy aktuális packaget egy másik package utasítással.

Szimbólumtábla

A 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, destruktor

Itt 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; }
Egy korábban importált modult a no utasítással távolíthatunk el.
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.

Néhány predefinit modul

integer E modul mondja meg a Perlnek, hogy használjon egész aritmetikát lebegőpontos aritmetika helyett.
Diagnostics A Perl interpreter több figyelmeztető üzenetet ír ki a program futása során.
Env Egy Perl modul, ami környezeti változókat importál.
POSIX A POSIX szabvány (IEEE 1003.1) Perlbeli interfésze.
Socket Betölti a C nyelv socket kezelő mechanizmusait.

Operátorok átlapolása

A Perl operátorainak nagyrésze átlapolható. Ehhez az overload pragma-t kell használni. A korábbi verziókban még meglevő, de már ott sem támogatott %OVERLOAD hash az 5.005-ös verziótól kezdve nem használható.
package Valami; use overload '+' => \&myadd, '-' => \&mysub; # stb. ... package main; $a = new Valami 57; $b = $a + 5;
Az átlapolás figyelembe veszi az @ISA hierarchiát, tehát minden olyan osztályban érvényes lesz, ami Valami-től örököl.

Az átlapolást megvalósító függvény 3 paramétert kap. Az első két paraméter a bináris operátor két oldalán álló érték. Mivel a metódushívás általános szabályai szerint az első paraméternek az adott osztályhoz tartozónak kell lennie, ezért (pl. 7 + $a) esetén előfordulhat, hogy ezen szabály betartásához az operandusokat meg kell cserélni, ami nem kommutatív műveletek esetén nem egészséges. Ezért a fordító a 3. argumentumban jelzi, hogy felcserélte-e az értékeket. Az unáris operátorokat a fordító úgy kezeli, mintha a 2. argumentum undef lenne.

Az argumentumok referenciaként kerülnek átadásra, ezért lehetőség van mellékhatások megvalósítására (mint pl. a ++ operátor esetén).

A következő operátorokat lehet átlapolni:

Elképzelhető, hogy a Perl nem találja az egyik operátorhoz rendelt metódust. Ennek kezelésére szolgál a "nomethod" nevű speciális operátor. Ha definiálva van, akkor ez hívódik meg; első három paraméterként megkapja a hiányzó művelet paramétereit, 4. paraméterként pedig a hiányzó művelet nevét.

Ha egy művelet nincs definiálva, a "fallback" nevű speciális operátor értéke dönti el a továbbiakat:

definiálatlan
Ekkor a Perl először elindítja a MAGIC AUTOGENERATION nevű eljárást, mely egy függvényt próbál generálni az adott operátorhoz. Ha ez nem megy, akkor a felhasználó által definiált "nomethod"-ot hívja. Ha ez sem működik, akkor exception lép fel.
TRUE
Minden az előző esetnek megfelelően zajlik, csak exception nem lép fel, hanem minden úgy folytatódik, mintha nem is lett volna átlapolás.
FALSE
A definiálatlan esettől abban tér el, hogy az autogenerálást nem próbálja meg.
Figyelem: a "fallback" és az öröklés kapcsolata még (az 5.005-ös verzióban) nem teljesen tisztázott, később változhat.

Az "=" speciális operátorra a következő esetben van szükség:

$a = $b; # két referencia, ami ugyanoda mutat $a++;
Ahhoz, hogy $b értéke ne változzon a művelet hatására, az $a változóról egy másolatot kell készíteni - ezt végzi el az "=" operátor, ha definiálva van.