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 nevü valamire?)
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, amelyiket akkor végrehajtódik, ha a ciklusban egy next utasítást hajtottunk végre. 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