
die foreach Schleife
den Schleifendurchgang wiederholen, wenn eine Bedingung
erfüllt ist - redo
die Schleife abbrechen werden, wenn eine bestimmte
Bedingung erfüllt ist - last
innerhalb einer Schleife einen Durchlauf überspringen
- next
verschachtelte Schleifen mit next, redo und
last
die for Schleife
die while Schleife
Es gibt wohl in allen Programmiersprachen die
gleichen Schleifen, abgesehen von Exoten wie apl. Perl ist
hier nur insofern exotisch, da es eine foreach Schleife
gibt, die in anderen Sprachen, mal abgesehen von PHP, nicht
existiert. Auf die foreach Schleife wurde im Zusammenhang
mit Arrays/Hashes schon eingegangen, siehe die Kapitel Funktionen
zur Bearbeitung von Arrays und Funktionen
zur Bearbeitung von Hashes.
Die foreach Schleife taucht nur
im Zusammenhang mit Arrays/Hashes auf. Die einfachste Variante
davon sieht so aus:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
foreach (@aprikose)
{
print "$_ \n";
}
Ist
kein Wert angegeben, dann übergibt die foreach Schleife
die Werte an die Sondervariable $_.
Das ist praktisch, weil auch match im Default Operator, siehe
Regular Expressions
, auf diese Variable angewendet wird.
Wer den Rückgabewert der foreach Schleife umlenken
will, schreibt vor die Klammer eine Variable:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
foreach $eigenschaften(@aprikose)
{
print "$eigenschaften\n";
}
Wer
sich nur bestimmte Werte des Arrays anschauen will, definiert
eine Laufvariable:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
foreach $z(1..$#aprikose)
{
print "$aprikose[$z]\n";
}
| den
Schleifendurchgang wiederholen, wenn eine Bedingung erfüllt
ist - redo |
|
Die Art wie Schleifen abgearbeitet werden, kann
durch last, next und redo feiner gesteuert werden.
Zuerst kommt ein Beispiel für redo. HALT ! DAS
BEISPIEL NICHT AUSLÖSEN ! ENDLOSSCHLEIFE !
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
foreach $z(1..$#aprikose)
{
print "$aprikose[$z]\n";
if ($aprikose[$z] eq steinig)
{
redo;
}
}
Das
Beispiel oben produziert eine Endlosschleife, da der Schleifendurchgang
immer wieder wiederholt wird, wenn er auf den Wert "steinig"
trifft.
Sinnvoll eingesetzt wird redo in folgendem Beispiel:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
$summe +=1;
if ($summe == 1)
{
redo;
}
}
print $summe;
Was
kommt raus? 4 oder 5? 5 kommt raus, weil bei 1 die Schleife
wiederholt wird.
| die
Schleife abbrechen werden, wenn eine bestimmte Bedingung
erfüllt ist - last |
|
Mit dem Befehl last kann die Schleife
abgebrochen werden, wenn eine bestimmte Bedingung erfüllt
ist:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
$summe +=1;
if ($summe == 3)
{
last;
}
}
print $summe;
Was
kommt da raus? Natürlich: 3.
Erreicht $summe den Wert 3, bleibt es bei diesem Wert, weil
die foreach Schleife mit last abgebrochen wird.
| innerhalb
einer Schleife einen Durchlauf überspringen - next |
|
Mit next kann innerhalb einer Schleife
ein Durchlauf übersprungen werden:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
if ($summe == 3)
{
next;
}
$summe +=1;
print "hallo $summe \n";
}
print $summe;
Dies
ist leider kein gutes Beispiel. Hat $summe den Wert 3, ist
die if Bedingung immer true, dass heißt der Schleifendurchlauf
macht nur noch next.
Ein besseres Beispiel ist:
@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
foreach $z(0..$#aprikose)
{
if ($aprikose[$z] eq "steinig")
{
next;
}
print "$aprikose[$z] \n";
}
Das heißt, steinig wird jetzt nicht
mehr gedruckt, weil die Schleife vorher abgebrochen wird.
| verschachtelte
Schleifen mit next, redo und last |
|
Wenn Schleifen in einander verschachtelt sind,
stellt sich die Frage, aus welcher Schleife mit next, redo
und last eigentlich gesteuert wird.
Es ist erst mal die Schleife, in der sich die Funktion befindet:
@aprikose=("gelb","steinig","suess","aehnlich wie Pflaume");
@pflaume=("blau","gross","suess sauer","aehnlich wie aprikose");
foreach $t(0..$#pflaume)
{
print "$pflaume[$t] \n";
foreach $z(0..$#aprikose)
{
if ($aprikose[$z] eq "steinig")
{
last;
}
print "$aprikose[$z] \n";
}
print "------------------------------------------------------------\n";
}
Als
Ergebnis liefert das Skript:
C:\test>perl test.pl
blau
gelb
------------------------------------------------------------
gross
gelb
------------------------------------------------------------
suess sauer
gelb
------------------------------------------------------------
aehnlich wie aprikose
gelb
------------------------------------------------------------
C:\test>
Die äußere foreach
Schleife wird durchlaufen, die innere wird immer an der selben
Stelle abgebrochen.
Soll die äußere foreach Schleife abgebrochen werden,
muss sie benannt werden (AUSSEN):
@aprikose=("gelb","steinig","suess","aehnlich wie Pflaume");
@pflaume=("blau","gross","suess sauer","aehnlich wie aprikose");
AUSSEN:foreach $t(0..$#pflaume)
{
print "$pflaume[$t] \n";
foreach $z(0..$#aprikose)
{
if ($aprikose[$z] eq "steinig")
{
last AUSSEN;
}
print "$aprikose[$z] \n";
}
print "------------------------------------------------------------\n";
}
Das Ergebnis dieses Skripts sieht dann
so aus:
C:\test>perl test.pl blau gelb
C:\test>
Wie deutlich zu erkennen
ist, beendet last jetzt auch die äußere Schleife.
Das in Bezug auf last, next und redo Gesagte gilt auch für
die for Schleife.
Die for Schleife hat folgende Syntax:
for (Initialisierung der Laufvariablen;Bedingung;Inkrementierungsfaktor
der Laufvariablen) { Befehle; }
Das sieht konkret so aus:
for ($i=0;$i<5;$i++)
{
print "Hallo, das ist die $i. Runde \n";
}
Meistens lässt sich das, was mit einer
while Schleifer realisierbar ist, auch mit einer for oder
foreach Schleife realisieren.
Allerdings verändert sowohl die foreach Schleife, als
auch die for Schleife die Inkrementierungsvariable nach einem
festen, vom Programmierer steuerbaren Muster. Das setzt voraus,
dass es ein solches Muster gibt. Es sind aber auch Fälle
denkbar, bei denen ein solches Muster nicht existiert. Nämlich,
wenn die Schleife dann starten soll, wenn ein anderer Prozess
irgendwas gemacht hat, man aber nicht weiß, wie lange
dieser andere Prozess dauert. Das heißt, es gibt kein
festes Muster.
Ein einfaches Beispiel ist:
$bedingung=1;
while ($bedingung)
{
print "Ich laufe, bis jemand die Bedingung umstellt";
$bedingung=0;
}
Diese while
Schleife macht einen Durchgang, weil innerhalb der while Schleife
die Variable $bedingung auf 0 gesetzt wird. 0 entspricht aber,
ähnlich wie undef, dem Wert false.
$bedingung könnte aber auch den Wert aus einer Datei
holen, den irgend ein anderer Prozess beschreibt. Bei der
konkreten Anwendung der while Schleife, sollte man wissen,
dass jeder Wert, der von 0 oder undef verschieden ist, als
true gilt:
while(undef)
{
print "da passiert nichts";
}
while(0)
{
print "Da passiert auch nichts";
}
$bedingung="Himbeertorte";
while($bedingung)
{
print "Einmal wird durchmarschiert";
$bedingung=0;
}
|
 |