Perl

A mottók:

"Mindenhez több mint egy út vezet."
A 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ó:
  1. Perl 5 nyelv rövid összefoglalása
  2. Indulás
  3. Adatstruktúrák
  4. Szintaxis ... utasítások
  5. Operátorok és precedenciájuk
  6. RegExp - szövegelés
  7. Operátorok átlapolása
  8. Beépített függvények
  9. Előre definiált változók
  10. Alprogramok írása
  11. Modulok
  12. Bonyolultabb struktúrák
  13. OOP
  14. Ötletek

Perl 5 nyelv rövid összefoglalása

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 nyelvet könnyű tanulni, mert
  1. ismert nyelvi elemeket tartalmaz
  2. kis rész ismerete is elég a használatához
  3. mindent azonnal ki lehet próbálni, mert gyors
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 (eredetileg szövegfile-ok feldolgozására találták ki, mint azt a neve is mutatja: Practical Extraction and Report Language). 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 asszociatí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 (pl. CGI program) 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.

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ás

Kezdetnek 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ák

Há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:

Ez az első karakter a változónak a kifejezésben betöltött szerepét kell, hogy takarja.

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ó indexe

Az 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

  • Előre definiált változók részben megtalálhatóak.

    Környezet

    A 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árok

    Skalá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 mindíg 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 = 1_000_000_000;		# 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ílusu
    	VEGE				# adatbevitellel (VEGE a zárószimbólum)
    	$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ök

    A 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,
    		);
    

    És az utóbbival ekvivalens alak:

    	%szinek = (			
    		'piros' , 0x00f,
    		'kék' , 0x0f0,
    		'zöld' , 0xf00,
    		);		#egyszerű felsorolás, párosával
    

    É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. Az értékadás akkor és csak akkor érvényes, ha a baloldalon legális balértékek szerepelnek.

    	($a,$b,$c)=(1,2,3)	#a változók sorban értéket kapnak
    	($a,$b,@maradek)=@valami	#ez is helyes
    
    Tömb balértékként használata csak utolsó elemnek érdemes, mert egy korábbi tömb az összes jobboldalt magába olvassa. Ez jó a lokális paraméterek átvételénél.
    A $[ változó mutatja, hogy a tömbök melyik indexen kezdődnek ( ez a C-ben 0 ). Ennek értéke módosítható ,ezért a következő két értékadás ekvivalens:
    	@tomb=()			#üressé teszi a tömböt
    	$#tomb=$[-1;			#a tömb hosszát -1-re állítja
    

    Skalár környezetben a tömb felhasználása a tömb aktuális hosszát adja vissza.
    Értékadásnál a résztömbök automatikusan elemenként bemásolódnak, így a keletkező tömb homogén lesz.

    	@tomb=(@lista1,@lista2,&alprg) 
    
    Egy asszociatív tömb skalár környezetben visszaadja, hogy van-e benne kulcs-érték pár. Ez csupán arra jó, hogy a hash-elő algoritmus hatékonyságát vizsgáljuk.

    Szintaxis ... utasítások

    A Perl program utasítások és dekralá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.
    Annak ellenére, hogy a nyelv UNIX-szűrő jellegű nyelvi elemeket is tartalmaz, minden utasítás csak egyszer kerül végrehajtásra, kivéve, ha ciklusban szerepel.

    A nyelvben az utasítások és dekralá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ás

    Egy 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 EXPR
    
    Egy üzenet kiírása feltételtől függően:
    	print "Hello kedves olvasó!\n" if $bobeszedu_program;
    

    Összetett utasítás

    Itt 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 BLOKK
    
    Az 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 BLOKK
    
    A 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) BLOKK
    
    Ez 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) BLOKK
    
    Ez 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 BLOKK
    
    Ez a végtelen ciklus volt...

    A ciklusokban használható a next, a last és a redo utasítás, melyek a ciklusbeli utasítások végrehajtását vezérlik. A fent említett next hatására a futás a ciklus elejére kerül, és a feltétel újratesztelésével folytatódik a működés. A redo ehhez hasonló, csak itt a feltétel tesztelése nélkül kerül a végrehajtás a ciklus első utasítására. A last pedig a ciklusból kiugrik, és az utána következő első utasításon folyik tovább a program végrehajtása.
    A három utasítás használatában érdekesség, hogy mindegyiket címkézni is lehet és ekkor az ugrások az adott címkével ellátott ciklusra vonatkoznak.

    Mivel a blokk egy egyszer lefutó ciklusnak tekinthető, ezért ezek az utasítások blokkban is használhatóak.

    A switch utasításra nincs külön forma, de van rá egypár lehetséges 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;
    	}
    
    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.

    Operátorok és precedenciájuk

    A C nyelvben érvényes szabályok érvényesek, és még van egypár - shell script-ekből ismerős - új operátor.

    operátor kiértékelés iránya leírás
    lista (,) balról jobbra kifejezések listája
    -> balról jobbra hivatkozás
    ++,-- nem asszociatív növelés, csökkentés
    ** jobbról balra hatványozás
    !,~,\ és unáris +,- jobbról balra nem, bináris nem, címoperátor, +, -
    =~,!~ balról jobbra szöveg illeszkedés, nem illeszkedés
    *,/,%,x balról jobbra szorzás, osztás, modulus, ismétlés
    +, -, . balról jobbra összeadás, kivonás, konkatenáció
    <<,>> balról jobbra balra, illetve jobbra shift
    unáris operátorok nem asszociativ pl. file tesztelés -f
    <,>,<=,>=,lt,gt,le,ge nem asszociatív szám illetve szöveg összehasonlítása
    ==,!=,<=>,eq,ne,cmp nem asszociatív szám illetve szöveg összehasonlítása
    & balról jobbra bináris AND
    |,^ balról jobbra bináris OR és XOR
    && balról jobbra logikai AND
    || balról jobbra logikai OR
    .. nem asszociatív tartomány
    ?: jobbról balra feltételes értékadás
    =, +=, -=, *= ... jobbról balra értékadás operátorai
    , => balról jobbra vessző és kulcs operátor
    lista operátorok nem asszociatív lista manipulációk
    not balról jobbra logikai NEM
    and balról jobbra logikai ÉS
    or, xor balról jobbra logikai VAGY-ok

    Itt csak az ismeretlennek tűnő operátorokat fogom kiemelni:

    címoperátor
    olyan mint a C nyelv & operátora; visszaadja az operandus objektum címét (alprogramokra is megy!)
    ismétlés
    egy szöveget meg lehet ismételni néhányszor, pl.: "ha"x3 == "hahaha"
    konkatenácó
    szövegek összefűzése, pl.: "ha"."ha" == "haha"
    file tesztelés
    ezek a shell programokban megszokott file tesztelő operátorok, pl.: -f "hello.c" akkor igaz, ha a hello.c file létezik
    szöveg összehasonlítás
    Erre a lt,gt,le,ge,eq,ne operátorok szolgálnak. Ha szövegeket az == operátorokkal hasonlítgatjuk, akkor azok memóriabeli címei kerülnek összehasonlításra, nem tartalmai!
    cmp értéke -1, 0, vagy 1 lehet a szövegektől függően.
    szám összehasonlítás
    Szokásos operátorokon kívül a <=> szerepel itt. Ennek -1 az értéke, ha az első szám nagyobb, 1, ha a második, és 0, ha egyenlő a két szám. Ez az operátor - az előbb említett cmp operátorhoz hasonlóan - főleg rendezéseknél használható jól.
    I/O
    Az alapvető és legfontosabb I/O operátor a < és a >. Ha egy file leíróját ilyen jelek közé rakjuk, akkor egy sort olvashatunk belőle. A beolvasott sor automatikusan a $_ változóhoz rendelődik, ha nem adunk meg mást.

    Egy egyszerű cat (UNIX cat parancs) így is leírható:

    	while(<STDIN>)
    	{
    		print $_;  # print; is lehetne, hiszen az $_ az
    		           # alapertelemezett argumentum
    	}
    	
    Megjegyezendő még, hogy a C nyelv három operatora nem szerepel a nyelvben, ezek a következők:

    A szövegekhez még járul egypár "idézőjel" operátor

    általában hivatalos jelölés értelme megjegyzés
    ''q{}szöveg literález a "szó szerinti" szöveg literál
    ""qq{}szöveg literálváltozókat helyettesíti a szövegben
    ``qx{}parancsaz adott szöveget, mint egy shell parancssort végrehajtja
    qw{}a szövegből egy szólistát csinálpl.: paraméterátadás
    //m{}mintaillesztésváltozókat értékükkel helyettesíti
    s{}{}csereváltozókat értékükkel helyettesíti
    tr{}{}betücsereaz szövegeket mint cseretáblát használja

    Mintaillesztés

    Szövegkeresés netovábbja.

    Használat

    A mintaillesztést több dologra is lehet használni a =~ vagy a !~ operátorokkal:

    Módosítók

    A // után általában írhatunk valamilyen karaktert, ami a keresést egy kicsit módosítja:
    i kis- és nagybetüket nem különbözteti meg
    m többsoros szövegben keres
    s a szöveget egyetlen sorként kezeli
    x kibővített keresési mód

    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 szintaxszissal í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ések

    Egy 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 következő karakter speciális
    ^ a sor elejéhez illeszkedik
    . egy tetszőleges karakterhez illeszkedik (kivéve az újsort)
    $ sor végéhez illeszkedik
    | alternatívák jelölése
    () csoportosítás
    [] karakter-osztály kijelölése

    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/;	# hamis
    

    A 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:
    * 0 vagy több
    + 1 vagy több
    ? 0 vagy 1
    {n} pontosan n-szer
    {n,} n-szer vagy többször
    {n,m} n <= ismétlődések száma <= m

    Alapértelmezés szerint ekkor a leghosszabb ismétlődés fog illeszkedni ezekhez a részekhez. Ha minimális számu 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

    \t tabulátorjel
    \n újsor
    \r return
    \f form feed
    \v vertical tab
    \a csengő
    \e escape
    \033 oktális számrendszerben megadott karakter
    \x1b karakter hexadecimálisan
    \c[ kontrol karakter
    \l kisbetü
    \u nagybetü
    \L kisbetü \E-ig
    \U nagybetü \E-ig
    \E ...
    \Q metakarakterek normálisak \E-ig
    \w "szó" karakter (alfanumerikus és _)
    \W nem-szó karakter
    \s whitespace
    \S nem whitespace
    \d számjegy
    \D nem számjegy
    \b szóhatárhoz illeszkedik
    \B nem szóhatár
    \A string elejéhez illeszkedik
    \Z string vége
    \G oda illeszkedik, ahol az elöző illesztés végetért

    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ás

    Ha 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 kiejezé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` =~ /(..):(..):(..)/);
    

    Operátorok átlapolása

    A Perl operátorainak nagyrésze átlapolható. Ehhez a %OVERLOAD tömböt kell használni, mely az átlapolt operátorokhoz tartozó függvényeket tárolja.
    	package Valami;
    		%OVERLOAD = (
    			'+' => \&myadd,
    			'-' => \&mysub;
    			# stb.
    		);
    	...
    	package main;
    		$a = new Valami 57;
    		$b = $a + 5;
    
    Elképzelhető az az eset is, hogy nincsen definiált operátor az adott típusó változóhoz. Ennek kezelésére szolgál az %OVERLOAD tömbnek "fallback" nevű eleme. A "fallback" értékétől függően három eset lehetséges:
    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, ami ezekre az esetekre lett létrehozva. 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.

    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, bizosan megvan. Ha nem úgy viselkedik, ahogy várta, akkor érdemes igénybe venni a POSIX modult:

    	use POSIX;
    
    Ezek után már bitosan meglesz az összes POSIX függvény.

    Ha valakinek még ez sem elég, akkor igénybeveheti 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
    Megmonja, hogy ki hívta az aktuális kódrészletet...
    ($package, $filename, $line) = caller;
    chop
    Levágja a '\n' 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
    	
    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.
    do BLOCK
    Végrehajtja a BLOCK-ot majd az utolsó utasítás értékét adja vissza. Ha ciklusmódosítóval használjuk, akkor a ciklusmag még a tesztelés előtt biztos lefut.
    do EXPR
    Az EXPR-t, mint Perl forrásnevet használja, és végrehajtja a benne lévő utasításokat.Minden hívásnál újra kielemzi a fájlnevet, ezért nem érdemes például ciklusban használni.
    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.
    Ez a módja egy Perl prgram "fordításának".
    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)
    eval BLOCK
    A BLOCK futtatása az aktuális környezetben. A BLOCK egy string is lehet!
    exists EXPR
    Megmondja, hogy létezik-e az asszociatív tömb egy eleme, pl.: if exists $tomb{"eleme"} ...
    glob EXPR
    EXPR file-név teljesen kiterjesztve. Úgy működik mint a shell-ek file-név kiterjesztő algoritmusa.
    keys ASSOC_ARRAY
    ASSOC_ARRAY kulcsait adja vissza egy tömbben.
    local EXPR
    EXPR-ben felsorolt változók a blokkra nézve lokálisak lesznek. Ez a dinamikus láthatóságh.
    my EXPR
    EXPR-ben lévő vátozó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 karaktertek. Az így definiált változók inkább a C nyelv lokális változóihoz állnak közel, mert a külvilág számára teljesen láthatatlanok lesznek.
    		sub kiir 
    		{
    			my ($szoveg1, $szoveg2) = @_;
    			chop $szoveg1;
    			chop $szoveg2;
    			print $szoveg1, ':', $szoveg2, '\n\n';
    		}
    	
    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");	# 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-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.
    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ő!
    return
    Alprogramból érték visszaadása. Ha ez nem szerepel, akkor az alprogram utolsó utasításának értéke lesz visszaadva.
    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.
    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.
    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.
    unapck
    pack függvény ellenkezője
    use MODULE, LIST
    MODULE modul LIST-ben felsorolt 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.

    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-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:

    $_,$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.
    $[
    Ez a változó mutatja, hogy a tömbök hányadik elemén kezdődik adat. Ez állítható a különböző nyelvekben megszokotthoz igazodva.
    $`, $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, tahá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 mindg 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 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á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;
    

    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 jellegű 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!
    
    

    type glob

    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
    

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

    	$elso = 1;	# ez a $main::elso
    
    	package MODUL;	# uj modul kezdete
    
    	$masodik = 1;	# $MODUL::masodik
    	$elso = 1;	# $MODUL::elso
    
    	$main::elso = 2;# $main::elso
    
    A főmodul neveihez még a $::elso hivatkozással is hozzáférhetünk.

    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; }
    
    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ák

    A gondok mindíg 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ása

    1. Legegyszerűbb a \ operátor használata. Ezzel egy újabb hivatkozást készithetünk egy változóra (egy már biztosan van a szimbólumtáblában):
      	$scalarref = \$scalar;
      	$arrayref = \@ARGV;
      	$hashref = \%ENV;
      	$coderef = \&handler;
      	
    2. 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álata

    Nagyon egyszerű egy referanciát használni: a programban egy változó neve helyére bárhova beírhatunk egy megfelelő típusú referenciát tartalmazó vátozót.
    1. Az egyszerű esetek, amikor egy egyszerű struktúrát szeretnénk használni:
      	$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;
      	
    2. Bármilyen hely, ahol egy referenciát kapnánk meg, helyettesíthető egy blokkal, amely értéke a referencia lesz:
      	$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. eset
      	
      Itt az 1. és 2., illetve a 3. és 4. eset egyenértékű.

    3. A fenti esetek egyszerűsítésére szolgál a -> operátor:
      	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;
      	

    Szimbólikus hivatkozások

    Ha 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::ize
    
    Ha ez a szabadság nem tetszik nekünk, akkor megköthetjük kezünket a use strict; használatával.

    OOP

    Lehet enélkül manapság nyelvet készíteni?

    Amit a Perl objektumokról tudni kell:

    1. Egy objektum csak egy egyszerű referencia, amely történetesen tudja, hogy melyik osztályhoz tartozik.
    2. Egy osztály egy package, amely tudja az objektum hivatkozásokat kezelni, és van némi támogatása az öröklésre.
    3. Egy metódus az egy egyszerű alprogram, amelynek az első paramétere egy objektum referencia vagy egy package-név lesz.

    Objektum

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


    Az objektumokat újra meg lehet áldani. Ekkor az objektum az új osztályba kerül, az eredeti osztályát "elfelejti", hisz egy objektum egyszerre csak egy osztályhoz tartozhat. Ezek után az új osztálynak kell gondoskodnia az eredeti adattagokkal kapcsolatos teendőkről. ld.Destruktorok

    Osztály

    Az 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ömbbö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!

    Nyilvánvalóan az adattagok öröklésére is szükség van egy objektum-orientált nyelvben, ez a Perlben az @ISA tömb segítségével megvalósítható.

    	package A;
            sub new {
                    my $type = shift;
                    my $self = {};
                    $self->{'a'} = 42;
                    bless $self, $type;
            }
    
            package B;
            @ISA = qw( A );		# A a B ősosztálya
            sub new {
                    my $type = shift;
                    my $self = A->new;
                    $self->{'b'} = 11;
                    bless $self, $type;
            }
    
            package main;
            $c = B->new;
            print "a = ", $c->{'a'}, "\n";
            print "b = ", $c->{'b'}, "\n";
    

    Metódus

    Semmi különös jelölés nincsen rájuk, kivéve a destruktorokat.

    Alapvetően kétfajta metódus van:

    statikus metódus
    Ez első paraméterében az osztály nevét kapja meg:
    	package ValamiUj;
    	sub holvagyok {
    		my ($neve) = @_;
    		print "holvagyok: $neve\n";
    	}
    	
    Ez a következőképpen hívható:
    	ValamiUj->holvagyok();
    	
    "rendes" metódus
    Ez az első paraméterében egy referenciát vár.
    	package ValamiUj;
    	sub new {
    		my $self = {};
    		bless $self;
    		$self->{elso} = 1;	# ez {"elso"}-vel egyenértékü
    		$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
    	

    Destruktor

    Destruktor is definiálható az osztályhoz, ha a modulban megadunk egy DESTROY nevű eljárást. Ez akkor lesz meghívva, amikor az utolsó hivatkozás is megszűnik az adott objektumra, vagy a program futása befejeződik.
    Nincs rekurzív destruktor-meghívás, vagyis az újraáldott objektum eredeti osztályára vonatkozó destruktort explicit meg kell hívni. Az objektumban tárolt adattagokra azonban a destruktor meghívása megtörténik.

    Ötletek

    Itt csak néhány ötletet mondok el, amik eddigi programjaimban jól jöttek:

    Jó szórakozást!

    Ezt a dokumentumot Frohner Ákos írta.
    Néhány kiegészítéssel Szabó Richárd látta el.

    Ennek a dokumentumnak a lemásolása illetve terjesztése csak teljes egészében történhet, a szerzőket megjelölő sorokkal együtt.