A Perl az utasításokat egymás után hajtja végre, úgy
mint a C. Végül is nem ez az egyetlen hasonlóság. Az
utasításokat általában pontosvesszõ zárja le,
de nem feltétlenül kell, ez elhagyható egy blokk utolsó
utasításánál.
Majdnem elfelejtettem. Egy program blokk, azaz utasítások egy csoportja { és
} között van. Ez kívülrõl úgy tekinthetõ, mint egy
utasítás. Belül lehetnek utasítások, lokális
változók.
Viszont van if, while, do, unless. Röviden:
if( kifejezés ) blokk
vagy
if( kifejezés ) blokk else blokk
És már most érdemes észrevenni, hogy nem utasítás,
hanem blokk szerepel itt is és más szerkezetekben is, azaz szintaktikusan
hibás a
if( $bela eq '3' ) $geza= 2 else $juli=4
szerkezet. Ehelyett a
if( $bela eq '3' ){ $geza= 2 }else{ $juli=4 }
használandó. És ez nagyon, nagyon jó. Vagy nem. Szóval
attól függ, hogy a C vagy a PASCAL lelkület bújik elõ belõled.
Rossz, mert eszelõsen sokat kell gépelni (amíg meg nem tanulod, hogy lehet
utasítás if kifejezés
alakban is használni), viszont baromi jó, mert nincs vele gond, hogy kell, vagy
nem kell, szabad vagy nem szabad az else elõtt pontosvesszõt használni,
és akkor az az else most melyik if-hez tartozik?
if ! kifejezés
helyett használható
unless kifejezés
Lassulunk, pörgessük fel! Ciklusok:
while( kifejezés ) blokk
elején tesztel, és ami a végén tesztel:
do blokk while( kifejezés )
Nincs until! Viszont van for minden mennyiségben:
for( kif1 ; kif2 ; kif3 ) blokk
pontosan úgy, mint C-ben, de van itt valami jobb is:
for $valtozo ( lista ) blokk
Ez a ciklus végigmegy a lista összes elemén, és $valtozo
minden egyes ciklus lefutásra az aktuális lista elem. Erre az idõre
ez a változó lokális, utána ugyanaz az értéke, mint ami
elõtte volt. Ebbe beleértendõ az is, ha az értéke undef volt.
Egy ciklusból ki lehet jönni elõbb is, mint ahogy az véget érne.
Ha valahol a ciklus belsejében végrehajtódik egy last
utasítás, akkor a ciklus befejezõdik. (Hé, C programozók! Nem
emlékeztet ez valami break-re?)
Ha egy ciklus elõtt egy cimke van, akkor a last utasításban erre
lehet hivatkozni, és akkor nem feltétlenül a legbelsõ ciklus futása
szakad csak meg, hanem a körülötte levõké is, egészen a
cimkézett ciklusig.
Ehhez hasonlóan létezik egy olyan utasítás, amelyik újrakezdi
a ciklust. Ezt a Perl next-nek hívja. (Hopp! Hopp! Rémlik valami continue?)
Természetesen itt is meg lehet adni cimkét.
És most jön valami érdekes: a ciklus után meg lehet adni egy
continue blokkot, amelyik akkor hajtódik végre, ha a ciklusban egy next
utasítást adtunk meg. Viszont van egy redo utasítás,
amelyik még ezt is kikerüli, és így indítja újra a ciklust.
Most már elég sokat dumáltunk, lássunk egy példát:
$i = 0;
while( $i < 7 ){
$i ++;
print "start $i\n";
next if $i == 1;
redo if $i == 2;
last if $i == 4;
print "end $i\n";
}continue{
print "$i countinue\n";
}
és amit kiír:
start 1
1 countinue
start 2
start 3
end 3
3 countinue
start 4
Biztos, hogy ezt írja ki, mert ezt a jegyzetet nem tiszta HTML-ben írom,
hanem elõször átengedem egy (természetesen Perl-ben írt) makro
preprocesszoron, amelyik többek között berakja a szövegbe a programot, meg amit
kiírt azt is. Emberi hiba kizurvu.
Van goto utasítás is a nyelvben. Méghozzá nem is
akármilyen. Ha valaki akarja, akkor használhatja a szokásos goto CIMKE
alakot, de mivel a nyelv teljesen interpretált, ezért a CIMKE helyén
szerepelhet bármilyen kifejezés, amelyik egy címke nevét adja meg.
(Ez például erõsen megnehezíti azok dolgát, akik
fordítót írnak a nyelvhez.)
Ha valakinek még ez sem elegendõen perverz, akkor használható a
goto &NAME alak, amelyik a NAME szubrutint hívja meg, de úgy, hogy
onnan már nem ide, hanem a goto utasítást tartalmazó
szubrutint meghívó függvénybe tér vissza a vezérlés.
(Ha még nem jutottál el odáig, akkor csak annyit, hogy a szubrutinokat a
&NAME alakban kell meghívni.)
Nézzünk egy goto példát:
goto LABEL1;
print "Ezt nem írom ki\n.";
LABEL1: print "Ezt kiírom.\n";
$i = 2;
goto ['LABEL00','LABEL10','LABEL20','LABEL30']->[$i];
LABEL00: print 'LABEL00'; goto ENDE;
LABEL10: print 'LABEL10'; goto ENDE;
LABEL20: print 'LABEL20'; goto ENDE;
LABEL30: print 'LABEL30'; goto ENDE;
ENDE:;
&sub1;
&sub2;
sub sub1 {
print "\nsub1\n";
goto &sub2;
}
sub sub2 {
my @c = caller();
print " @c sub2\n";
}
és amit kiír:
Ezt kiírom.
LABEL20
sub1
main gototest.pl 12 sub2
main gototest.pl 13 sub2
|