Weitere interessante Möglichkeiten werden mit Kontrollstrukturen und Schleifen eröffnet. Perl unterstützt viele verschiedene Arten von Kontrollstrukturen. Wir werden hier ein paar davon ansehen.
Um jedes Element eines Arrays oder einer andern Listenstruktur (wie zun Beispiel die Zeilen einer Datei) zu durchlaufen, kann foreach
verwendet werden.
Das sieht folgendermaßen aus:
foreach my $morsel (@food) # Gehe der Reihe nach durch
# @food und nenne das
# Element $morsel
{
print "$morsel\n"; # Ausgabe des Elementes
print "Yum yum\n"; # That was nice
}
Die Anweisungen, die jedesmal durchgeführt werden sollen, müssen in geschweiften Klammern angegeben werden.
Falls @food
leer wäre, würde der Block in geschweiften Klammern nie durchlaufen.
Die nächsten Anweisungen testen die Gleichheit zweier Ausdrücke.
In Perl wird jede Zahl ungleich Null und jeder nicht leere String als true
(wahr) betrachtet.
Die Zahl 0
, "0"
als String und der leere String (""
) sind false.
Hier sind ein paar Tests auf Gleichheit für Zahlen und Strings:
$a == $b # $a numerisch gleich $b?
# Achtung: Nicht = verwenden
$a != $b # $a numerically ungleich $b?
$a eq $b # $a gleicher String wie $b?
$a ne $b # $a und $b nicht der gleiche String?
Es gibt auch die logischen AND, OR und NOT:
($a && $b) # ist $a und $b true?
($a || $b) # ist entweder $a oder $b true?
!($a) # ist $a false?
Die for
-Schleife funktioniert so ähnlich die foreach
.
my @array = ('Hund', 'Katze', 'Maus');
for my $var (@array)
{
print "$var\n";
}
for (1 .. 10) {
print "$_\n"; # Verwendung der impliziten Laufvariable
}
print "Heute ist ein guter Tag" for 1 .. 3; # drei mal ausgeben
for( my $i = 0; $i < 10; $i++ ) {
print "Iteration Nummer $i\n";
}
Die letztgenannte Variante gibt es auch in den meisten anderen Programmiersprachen. Die abstrakte Form stellt sich so dar:
for (init; test; inkr)
{
# do something
}
Zuerst wird init ausgeführt. Damit wird die Zählervariable initialisiert. Falls test true ist, wird der Block von Anweisungen in den geschweiften Klammern ausgeführt. Nach jedem Durchgang wird inkr ausgeführt. Mit der folgenden for-Schleife werden die Zahlen 1 bis 9 ausgegeben:
for ($i = 1; $i < 10; $i++) # Starte mit $i = 1
# falls $i < 10
# Inkr. $i vor Block
{
print "$i\n";
}
Die reservierten Wörter for und foreach können für beide Strukturen verwendet werden. Perl merkt dann schon, was gemeint ist!
Das folgende Programm liest eine Eingabe von Keyboard und wiederholt die Anfrage, bis das korrekte Passwort eingegeben wurde.
#!/usr/local/bin/perl
use strict;
use warnings;
print "Password? "; # Fragt nach Input
my $a = <STDIN>; # liest input
chop $a; # löscht \n am Ende
while ($a ne "fred") # Solange $a falsch ist
{
print "sorry. Again? "; # Fragt wieder
$a = <STDIN>; # liest
chop $a; # löscht \n am Ende
}
Die while-Schleife sollte soweit klar sein. Wie immer haben wir einen Block von Anweisungen in geschweiften Klammern. Ein paar Dinge können wir hier noch erwähnen: Erstens können wir von STDIN lesen, ohne es zuerst geöffnet zu haben. Zweitens wird mit der Eingabe des Passwortes auch ein newline-character in $a abgespeichert. Drittens ist die chop-Function dazu da, den letzten Buchstaben eines Strings abzuschneiden, in diesem Fall den newline-character.
Um das Gegenteil zu testen, können wir die until-Schleife in genau gleicher Weise verwenden. Damit wird der Block solange ausgeführt, bis der Test true ist und nicht solange er true ist.
Eine andere Art vorzugehen, ist die Verwendung des while- oder until-Tests am Ende des Blocks anstatt am Anfang. Dazu benötigt man noch den do-Operator, welcher den Blockanfang markiert. Falls wir die Meldung sorry. Again weglassen, könnten wir das Passwortprogramm folgendermassen schreiben:
#!/usr/local/bin/perl
do
{
print "Password? "; # Fragt nach Input
$a = <STDIN>; # liest Input
chop $a; # löscht \n
}
while ($a ne "fred"); # Nochmals solange falscher Input
Wir ändern das Programm der letzten Übung, indem jede Zeile einzeln eingelesen werden soll und die Ausgabe am Anfang die Zeilennummer aufweist. Die folgende Struktur ist vielleicht hilfreich:
while (my $line = <INFO>)
{
...
}
Danach hätten wir noch gerne die Zeilennummern im folgenden Format: 001, 002, ..., 009, 010, 011, 012., etc. Um das zu erhalten, braucht es nur einen Zusatz von vier Buchstaben in einer Zeile. Perl ist da sehr flexibel...