Program szerkezetek

A Perl az utasításokat egymás után hajtja végre, úgy mint C nyelvben. 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 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


Verhás Péter Home Page . . . . . . Perl röviden, tartalomjegyzék