Weiter Zurück Inhalt

2. Grundlegende Elemente der Sprache

Perl ist eine Sprache, deren einzelne Funktionselemente oft anderen Sprachen entlehnt sind, sofern eine bestimmte Funktionalität in jener Sprache in vorbildlicher Weise bereitgestellt wird. Daher werden viele Programmierer in Perl vertraute Konstrukte vorfinden. Außerdem hat Perl auch seine eigenen, höchst leistungsfähigen Konstrukte und Datenstrukturen. In diesem Kapitel wird daher eine Übersicht über die syntaktischen Konventionen, die Datentypen, die wichtigsten Funktionen und Operatoren sowie eingebaute Variablen gegeben.

2.1 Syntaktische Konventionen von Perl-Programmen

Im Gegensatz zu Pascal-Programmen, die einen BEGIN/END.-Block benötigen, oder C-Programmen, die immer eine Funktion namens main() aufweisen müssen, werden Perl-Programme in der Regel in der Reihenfolge ihres Quelltextes abgearbeitet. Das einfachste Perl-,,Programm'' ist leer und bereitet dennoch der Laufzeitumgebung keine Probleme. Das kleinste Perl-Programm, das wirklich etwas bewirkt, sieht so aus:


print "Hallo, Welt!\n"; # Gibt einen bekannten Gruß aus

Hieran können wir bereits sehen, daß die Argumente einer Funktion nachgestellt werden, daß wörtlicher Text in doppelte Hochkommata eingeschlossen ist (was aber nicht zwingend ist, wie vieles in Perl nicht zwingend ist. Siehe Kapitel Wörtlicher Text und Begrenzer. Zwingend scheinen nur Kommentare wie diese zu sein.), daß Statements mit Semikola abgeschlossen werden

Zumindest fast immer; nur das letzte Statement eines Blocks (s. BLOCK) ist von dieser Regel ausgenommen.
, und daß Kommentare zum Quelltext mit # eingeleitet werden. Kommentare dürfen sich übrigens nicht über mehrere Zeilen erstrecken; sollte ein mehrzeiliger Kommentar benötigt werden, so ist jede Kommentarzeile neu mit # einzuleiten. Außerdem muß dem Ausgabebefehl ausdrücklich mitgeteilt werden, daß die Textzeile mit einem Zeilenumbruch (\n) endet.

2.2 Ausführung von Perl-Programmen

Je nach Betriebssystem unterscheiden sich die Ausführungsmöglichkeiten für Perl-Skripte. In UNIX-ähnlichen Betriebssystemen gibt es fast immer die Möglichkeit, die Skripte mit einer Kommentarzeile zu beginnen, die den Pfad zum Perl-Interpreter enthält. Wenn das Perl-Skript als ausführbar gekennzeichnet ist, kann es direkt aufgerufen werden. Sollte dies nicht möglich sein, so kann auch Perl aufgerufen und das Skript als Argument übergeben werden.

Ausführung auf UNIX-ähnlichen Systemen

Unser erstes Beispiel Hallo, Welt! läßt sich auf UNIX-typische Weise so schreiben und ausführen:


$ chmod 755 hallo
$ cat hallo
#!/usr/bin/perl
print "Hallo, Welt!\n"; # Gibt einen bekannten Gruß aus
$./hallo
Hallo, Welt!
$

In den meisten der folgenden Beispiele wird die erste Skriptzeile mit dem Interpreter-Aufruf in der Regel weggelassen.

Ausführung auf DOS-basierenden Systemen

Für DOS- und OS/2-basierende Systeme gibt es die Möglichkeit, Batch-Dateien zu schreiben (etwa namens HALLO.BAT), die für den Kommando-Interpreter (etwa COMMAND.COM) den Aufruf des Perl-Interpreters und den Skripttext enthalten können. Genaue Angaben zum Ablauf von Perl-Programmen finden sich in der perlrun-manpage.

Ausführung auf Windows-basierenden Systemen

Genaueres über Installation und Einsatz von Perl auf Windows-basierenden Systemen findet sich unter http://www.activestate.com/ActivePerl.

Ausführung auf Mac-basierenden Systemen

Genaueres über Installation und Einsatz von Perl auf Mac-basierenden Systemen findet sich unter http://www.macperl.com/.

2.3 Variablentypen

Eines der herausragenden Merkmale von Perl ist die schwache Typisierung der Sprache. Es gibt in der praktischen Arbeit eigentlich nur zwei wirklich voneinander verschiedene Variablen- und Datentypen, die mit einfachen Operationen ineinander überführt werden können. Perl beschwert sich auch nur dann beim Benutzer über einen falschen Datentyp, wenn im gegebenen Kontext wirklich keinerlei Möglichkeit besteht, die Variable mit dem fraglichen Datum zu evaluieren.

Nach Konvention und Namensraum werden allerdings nicht zwei, sondern drei wichtige Daten- und damit Variablentypen unterschieden, nämlich Skalare, Arrays oder Listen, und namentlich referenzierte Arrays, auch Hashes genannt. Neben diesen klassischen Variablen, die mit Operatoren zu Ausdrücken verknüpft die Argumente von Funktionen bilden, gibt es auch Bezeichner für Datei-Handles, Formatvorlagen und andere Dinge, aber diese Bezeichner werden im Regelfall nicht als Operanden, sondern als Argumente eingesetzt.

Grundsätzlich gilt für Variablen in Perl, daß sie nicht deklariert werden müssen. Ihr erstmaliges Erscheinen im Programmtext führt lediglich dazu, daß ihr Wert auf die spezielle Größe undef gesetzt wird. Wenn versucht wird, den Wert einer solchermaßen nicht definierten Variablen auszulesen, wird nach außen hin die passende Leergröße, also beispielsweise eine leere Zeichenkette, ausgegeben.

Skalare

In Perl sind die sogenannten Skalare Platzhalter, die sowohl Zeichenketten als auch numerische Werte enthalten können. Es entfällt damit die Unterscheidung ,,klassischer'' Programmiersprachen nach INT, LONGINT, STRING, CHAR, REAL und wie die Typen in C und Pascal benannt werden.

Skalare fangen immer mit dem Typbezeichner $ an, durch den ein eigener Namensraum definiert wird: $kalar ist eine skalare Variable mit dem Namen kalar. Da Variable in Perl weder deklariert noch initialisiert werden müssen und Skalare jederzeit Zeichenketten und numerische Werte enthalten können, ist es somit möglich, folgende Zeilen ohne Laufzeitfehler abzuarbeiten:


$a=4;        # $a ist numerisch
print $a;    # `4' wird ausgegeben
$a="vier";   # $a ist jetzt eine Zeichenkette
print $a;    # `vier' wird ausgegeben

Variable werden immer im Kontext evaluiert (oder interpoliert, um im Perl-Jargon zu bleiben). Daher stellt sich die Frage, ob `4' als Zeichenkette oder als numerischer Wert behandelt wird, eigentlich nicht, da dies durch die Operatoren bestimmt werden kann, denen die skalare Variable als Operand vorgelegt werden kann. Ausführliche Beispiel folgen im Kapitel Operatoren.

Listen und Arrays

Die nächste Daten- und Variablengruppe, die Perl zu bieten hat, sind Listen, als Variable auch Array genannt.

Listen sind Sammlungen von Skalaren. Wenn diese Sammlungen in einer Variable gebündelt werden sollen, wird dazu ein Array benutzt. Arrays können also in ihren einzelnen Listenelementen Zeichenketten und numerische Werte in beliebiger Verteilung enthalten.

Arrays werden durch ein vorangestelltes @ gekennzeichnet, etwa so: @rray ist die Listenvariable rray. Der Namensraum der Arrays ist von dem der Listen abgegrenzt, so daß zwischen $worte und @worte keine Konflikte auftreten.

Einzelne Elemente eines Arrays werden mit Subskriptnotation bezeichnet, deren Startwert Null ist. Es handelt sich hierbei um den Versatz in die Elementenliste hinein, nicht um die Nummer des Elements. $liste[3] bezeichnet daher das vierte Element von @liste. Es erscheint vielleicht die Dollarnotation merkwürdig, aber per Definition ist das einzelne Element eines Arrays ein Skalar, der daher entsprechend gekennzeichnet sein muß.


@a=(4,5,6,'a','b','c'); # @a entält drei numerische Werte und drei Zeichenketten
print @a;               # `456abc' wird ausgegeben, in Listenkontext
print @a[1,2];          # `56' wird ausgegeben, in Listenkontext
print $a[1];            # `5' wird ausgegeben, nun ein Skalar

Namentlich referenzierte Arrays (Hashes)

Einer der mächtigsten Datentypen Perls sind die namentlich referenzierten Arrays oder Hashes (im Perl-Jargon). Ähnlich wie Arrays enthalten Hashes Sammlungen von Skalaren. Anders als bei Arrays erfolgt der Zugriff auf den einzelnen Wert jedoch nicht über eine Indexnummer, sondern über einen namentlich vergebenen Schlüssel. Perls Hashes sind daher so etwas wie rudimentäre Datenbanken in Variablenform.

Perls namentlich referenzierte Array-Bezeichner werden durch ein vorangestelltes % markiert. Auch hierdurch wird ein eigenständiger Namensraum erschlossen, so daß es keine Konflikte mit gleich buchstabierten Variablenbezeichnern anderen Typs gibt.


%telno=('Otto'          => 4711,
        'Schorschi'     => 123456,
        'Jupp'          => 654321
        );

print $telno{'Otto'};           # Druckt '4711'

print $telno{'Heinz'};          # Druckt nichts, da 'Heinz' nicht definiert

$telno{'Heinz'}='0800-HEINZ';   # Zufügen eines
                                # neuen Elementes

print $telno{'Heinz'};          # Druckt '0800-HEINZ'

Datei-Handles

Die nächste, häufig gebrauchte Variablenart sind Datei-Handles. Aus Konvention werden sie immer mit Großbuchstaben geschrieben, also z. B. MYLISTING, aber dies ist nicht zwingend notwendig.

Datei-Handles werden mit der Funktion open erzeugt. Einfache Beispiele der häufigsten Anwendungen folgen hier, interessehalber sei jedoch auf den vollen Funktionsumfang verwiesen, der in der manpage perlfunc unter dem Eintrag open zu finden ist.


open(MYLISTING,'mylist.txt');   # Bindet Datei mylist.txt an Handle MYLISTING
                                # und öffnet die Datei nur zum Lesen
$line=<MYLISTING>;           # Liest aus mylist.txt eine Zeile ein

open(MYRESULT,'>myresult.txt'); # Bindet Datei myresult.txt an Handle MYRESULT
                                # und öffnet die Datei neu zum Schreiben.
print MYRESULT $line;           # Eine eventuell vorhandene Datei gleichen
                                # Namens wird mit dem Öffnen überschrieben.

open(MYLOG,'>>mylog.txt');      # Bindet Datei mylog.txt an Handle MYLOG
print MYLOG $line;              # und öffnet die Datei zum Schreiben, ohne
                                # sie auf Null zurückzusetzen.

open(DATABASE,'+<datenbank.db');# Öffnet eine Datei zum Lesen *und* Schreiben

open(MYLIST,'|sort >list.txt'); # Übergibt den Inhalt von MYLIST an
                                # Pipe mit Weiterleitung auf den
                                # sort-Befehl des Betriebssystems;
                                # die Ausgabe wird in der Datei
                                # 'list.txt' abgelegt.

Da Datei-Handles STDIN, STDOUT und STDERR sind vordefiniert und bezeichnen die Standardeingabe, die Standardausgabe und die Standardfehlerausgabe. Wird im Programmtext keine andere Datei angegeben, so beziehen sich Lese- und Schreibvorgänge immer auf die Standardein- und ausgabekanäle. Daher druckt das allererste Beispiel in diesem Text sein Hallo, Welt auch ohne weitere Befehle auf den Bildschirm.

2.4 Vordefinierte Variable

Perl hält einen großen Vorrat vordefinierter Variabler bereit, die teilweise explizit, teilweise auch implizit angesprochen werden können. Die wichtigste Variable ist $_, die den aktuellen Skalar enthält, der bei der letzten Leseoperation eingelesen wurde. Normalerweise wird aus einer Datei (nehmen wir hier STDIN an) mit dem Befehl $skalar=<STDIN> gelesen; der Verweis auf $skalar kann auch wegfallen, so daß die while-Schleife vieler Perl-Programme, mit der die Daten eingelesen werden (while (<STDIN>) {}), in Wirklichkeit while ($_=<STDIN>) {} heißt.

Alle Funktionsaufrufe, die normalerweise einen Skalar als Argument erwarten, weichen auf die Standardvariable $_ aus, wenn nicht explizit ein anderer Skalar angegeben wird. Die impliziten Variablen entsprechen den elliptischen Bezugskonstruktionen, denen man auch in natürlichen Sprachen begegnet:

- Hast Du gestern den Film gesehen?

- Nein, habe ich nicht.

Der Fragende weiß genau, daß sich die gegebene Antwort auf das Sehen des Films bezieht und nicht auf irgendwelche anderen Vorgänge und Tatsachen, etwa Pizza zu essen oder ein Buch zu kaufen.

Die vordefinierten Variablen erschweren am Anfang das Verständnis von Perl-Texten, wenn man rigide Definitionen erwartet. Perl ist in manchen Aspekten aber an natürliche Sprachen angelehnt und zeichnet sich durch ähnliche Abkürzungsmechanismen aus.

Es gibt nicht nur vordefinierte Skalare, sondern auch vordefinierte Arrays; mit dem einfachen Aufruf von split ; wird eine Zeile (in $_ enthalten) an den Leerstellen getrennt und die vorgefundenen Elemente einem Array namens @_ übergeben, mit dem man weiter operieren kann.

Wer sich einen genauen Überblick über die stattliche Familie der vordefinierten Variablen verschaffen möchte, kann Einzelheiten auf der manpage perlvar nachlesen.

Wer mit den vordefinierten und impliziten Variablen Probleme hat, kann an ihrer Stelle auch die Entsprechungen dieser Variablen in englischer Sprache verwenden. Dies muß allerdings Perl mitgeteilt werden, bevor dies möglich ist. Dies geschieht mit folgendem Aufruf in der Nähe des Programmbeginns:


use English;
#
while (<>) {
        print $ARG      # $ARG steht jetzt fuer $_
        }

Eine Liste aller in Klartext verfügbaren Variablen findet sich im Nußschalenbuch auf Seite 200 und in der manpage perlvar.

Tatsächlich haben wir soeben das erste Mal ein Modul aufgerufen. Der Erweiterbarkeit von Perl durch Module ist das Kapitel Module gewidmet.

2.5 Flußkontrolle

Während zunächst die einfachste Flußkontrolle darin besteht, alle Statements eines Programmtextes hintereinander zu schreiben, um sie dann in dieser Reihenfolge ausführen zu lassen, ist dies natürlich für viele Fälle unzureichend, da weder Wiederholungen von Programmteilen noch bedingte Ausführung möglich wären. Perl bietet nicht nur klassische Mittel wie if-Konstrukte und while-Konstrukte für bedingte und wiederholte Ausführung, sondern gestattet darüberhinaus eine erstaunliche syntaktische Freiheit beim Schreiben des Programmtextes.

Übrigens kann bereits die einfachste Reihung aller Statements ohne sichtbare Flußkontrolle in Form etwa einer while-Schleife in Perl ein sinnvolles Programm darstellen, das auf den gesamten Eingabetext angewandt wird. Zu diesem Zweck muß Perl allerdings mit bestimmten Einstellungen (siehe Kapitel Kommandozeilen-Optionen) aufgerufen werden.

Die wichtigsten Elemente für die Ablaufkontrolle werden nun angegeben, wobei zu bemerken ist, daß ein BLOCK unabhängig von der Zahl der enthaltenen Statements immer in geschweifte Klammern eingeschlossen sein muß. Die von C bekannte Methode, einzelne Statements als Block zuzulassen, gilt in Perl nicht. Auch einzelne Statements müssen immer in geschweifte Klammern gefaßt werden, wenn sie als Block auftreten sollen.

Hier nun die wichtigsten Schlüsselwörter:

if

prüft eine Bedingung und veranlasst gegebenenfalls die Ausführung eines Befehlsblocks.

Die allgemeine Form lautet:

if (Bedingung) BLOCK

Daher ist folgendes Beispiel korrekt:

if ($Alter>18) {print "Sie dürfen wählen!\n";}

Es ist allerdings auch möglich, die Reihenfolge umzustellen und die folgende Form zu benutzen:

Statement if (Bedingung) 

Daher ist folgendes Beispiel funktionsfähig:

Abfragen if ($query->param('Knopf') eq 'Query');

Der if-Konstrukt kann um eine Alternative ergänzt werden. Dazu dient das Schlüsselwort else:

if (Bedingung) BLOCK
else BLOCK

Daher ist folgendes Beispiel korrekt:

if ($Alter>18) {print "Sie dürfen wählen!\n";}
else {print "Sie müssen Ihre Eltern fragen!\";}

while

bewirkt die wiederholte Ausführung eines Blocks bei erfolgreicher Bedingungsprüfung.

Die allgemeine Form lautet:

while (Bedingung) BLOCK

In typischer Weise werden mit while Schleifen gebildet, mit denen über ganze Dateien iteriert wird:

while (<STDIN>) {
        # Mache etwas mit den von STDIN nach $_ eingelesenen Variablen
        }

unless

bewirkt das Gegenteil von if. Sobald eine Bedingung nicht erfüllt ist, wird ein Block ausgeführt.

unless (Bedingung) BLOCK

unless ($Alter>18) {print "Sie dürfen nicht wählen."}

for

bewirkt eine beschränkte Wiederholung eines Blocks. Die allgemeine Form ist:

for ([Anweisungen und] Bedingung) BLOCK

Ein funktionierendes Beispiel wäre:

for ($i=0; $i<=10; $i++) {print "$i;"}

Hier ist besonders hervorzuheben, daß alle drei Anweisungen in den runden Klammern nach for optional (!) sind. Daher ist auch der folgende Ausdruck gültig:

for (;;) { Actions }

Mit (;;)wird eine endlose Schleife initiiert, aus der kontrolliert ausgestiegen werden muß.

foreach

arbeitet für jedes Element der angegebenen Liste einen Block ab (eine Liste ist eine Sammlung von Skalaren). Die allgemeine Form ist:

foreach SKALAR (LISTE) BLOCK

Als LISTE kann sowohl eine Liste stehen, die von einem Operator im Listenkontext erzeugt wird, als auch ein Array, das eine Liste enthält, als auch eine wörtliche Liste. Daher sind die folgenden Beispiele funktionsfähig:

@worte=(Am, Anfang, war, das, Wort);
#
# @worte ist ein Array von Skalaren und daher eine LISTE..
#
# $wort ist eine Laufvariable.
foreach $wort (@worte) {print "-- $wort --\n";}
#
# Die LISTE ergibt sich nun aus dem Kontext: sort gibt eine Liste aus.
#
foreach $wort (sort @worte) {print "-- $wort --\n";}

2.6 Operatoren

Perl unterscheidet in vertrauter Weise zwischen Operatoren und Funktionen. Im Grenzfall ist ein und dasselbe Objekt je nach Aufrufart ein Operator oder eine Funktion; die Entscheidung fällt mit der Anwendung und der Schreibweise. Wenn das Argument eines Befehls in Klammern steht, ist es eine Funktion. Außerdem akzeptiert eine Funktion als Argument sowohl Ausdrücke als auch Literale, wohingegen für die Verküpfung von wörtlichen Operanden und Operatoren bestimmte Einschränkungen gelten (s.u., unäre Operatoren). Operatoren werden unterschieden nach:

wobei diese Aufzählung in der Darstellung des Nußschalenbuchs folgt. In der Praxis überschneiden sich diese Kategorien: so muß ein Vergleichsoperator muß explizit für Zahlen oder Zeichenketten ausgewiesen werden. Bestimmte Verknüpfungsoperatoren erzeugen mit Operanden verschiedener Art automatisch korrekte Ergebnisse, da implizit die Auswahl der richtigen Operation erfolgt. Gelegentlich werden allerdings scheinbar kryptische Ergebnisse erzeugt, die sich aber mit etwas Verständnis der Perl zugrundeliegenden Logik leicht entschlüsseln lassen:
$baer="Bär ";              # eine Zeichenkette
$wolf="Wolf";           # eine Zeichenkette
print $baer.$wolf;      # "Addition" von Zeichenketten,
                        # Resultat ist 'Bär Wolf'
print $baer+$wolf;      # Erzwungene numerische Addition, beide
                        # Variablen hatten den numerischen Wert
                        # "0", daher ist das Resultat "0" !

Für eine genaue Übersicht über alle Operatoren einschließlich Präzedenz und Assoziativität wird auf die manpage perlop sowie Kamel- und Nußschalenbuch verwiesen. Hier folgen einige ausgewählte Beispiele.

Operatoren für Zahlen und Zeichenketten

Perl unterscheidet nach Datentyp zwischen Operatoren für Textwerte und Operatoren für numerische Werte sowie nach Syntax zwischen unären, binären und ternären Operatoren.

Die Unterscheidung zwischen Zeichenketten und numerischen Werten ist besonders für Vergleiche von höchster Bedeutung, wie sich aus dem Vergleich der Skalare 2 und 11 einleuchtend ergibt. Als numerischer Wert ist 2 kleiner als 11, aber als Zeichenkette sortiert hätte es einen höheren Rang.

Daher muß man bei Vergleichsoperationen immer den Datentyp angeben, was durch die Wahl des passenden Operators geschieht:

# a gleich b?
if ($a == $b) {}                # numerisch
if ($a eq $b) {}                # Zeichenkette ("equal")

# a ungleich b?
if ($a != $b) {}                # numerisch
if ($a ne $b) {}                # Zeichenkette ("not equal")

# a kleiner als b?
if ($a <  $b) {}             # numerisch
if ($a lt $b) {}                # Zeichenkette ("less than")

# a größer als b?
if ($a >  $b) {}                # numerisch
if ($a gt $b) {}                # Zeichenkette ("greater than")

# a kleiner als oder gleich b?
if ($a <= $b) {}             # numerisch
if ($a le $b) {}                # Zeichenkette ("less than or equal")

# a größer als oder gleich b?
if ($a >= $b) {}                # numerisch
if ($a ge $b) {}                # Zeichenkette ("greater than or equal")

Ein weiterer nach Inhalt verschieden wirkender Operator ist beispielweise der Zufügungs-Operator (Additionsoperator für Zahlen, Konkatenationsoperator für Zeichenketten).

# Hinzufuegungen
$a=4;           # $a wird '4'
$b=5;           # $b wird '5'
print $a+$b;    # Die Zahlensumme wird ausgegeben
print $a.$b;    # Die 'Summe' der Zeichenketten wird ausgegeben

Interessanterweise gibt es auch Inkrementoperatoren für Zeichenketten, die das lateinische Alphabet als Zahlensystem mit der Basis 26+26 betrachten, das durch die Zeichen 'A' bis 'z' ausgedrückt wird, und einen Multiplikationsoperator für Zeichenketten.

# Inkrementoperationen von Zeichenketten
$n=x            # $n wird 'x'
print ++$n;     # Ausgegeben wird 'y'
print ++$n;     # Ausgegeben wird 'z'
print ++$n;     # Ausgegeben wird 'aa'

# Multiplikation von Zeichenketten
print '*' x 16; # Ausgegeben wird '****************'

Unäre Operatoren

Die von C bekannten unären Operatoren ++ und -- gibt es im numerischen Kontext auch in Perl:

$n=100;         # $n wird 100
print $n++;     # Gibt '100' aus; *anschließend* wird $n zu 101
print ++$n;     # Erhöht $n auf 102 und gibt diese Zahl aus
Ihre Anwendung im Zeichenketten-Kontext wurde eben schon vorgeführt.

Dateiprüfungs-Operatoren

Manchmal ist es wichtig, den konkreten Ablauf eines Perl-Programmes vom Vorhandensein und der Art einer Datei abhängig zu machen. In diesen Fällen greift man zu Dateiprüfungsoperatoren. Angenommen in $a sei ein Dateiname enthalten, so liefern die folgenden, beispielhaften Tests Boolesche Ergebnisse:

-e $a           # Wahr wenn Datei $a existiert
-r $a           # Wahr wenn Datei $a lesbar ist
-w $a           # Wahr wenn Datei $a schreibbar ist
-d $a           # Wahr wenn Datei $a ein Verzeichnis ist
-f $a           # Wahr wenn Datei $a eine gewöhnliche Datei ist
-T $a           # Wahr wenn Datei $a eine reine Text-Datei ist

2.7 Funktionen

Wie schon in der Einleitung zu Kapitel Operatoren gesagt, hängt die Klassifizierung eines bestimmten Befehls oft von der Aufrufsyntax und dem übergegebenen Datentyp ab. Grundsätzlich kann man sich aber an die Einteilung der Perl-manpages halten und alle Befehle, die in perlfunc erklärt sind, als Funktionen verstehen.

Es gibt bei Perl einen großen Schatz von Funktionen für die Verarbeitung von Zeichenketten und numerischen Werten und die Umwandlung zwischen diesen. Diese Funktionen, aus denen übrigens das Gros der meisten Perl-Programme aufgebaut ist, sind in allen Portierungen von Perl gleichermaßen verfügbar, weswegen es keine Probleme mit der Ausführung auf verschiedenen Rechnern geben sollte.

Darüberhinaus gibt es bei Perl noch eine Gruppe von Funktionen, die auf bestimmte Schnittstellen des Betriebssystems aufsetzt und daher nicht auf allen Rechnertypen gleich implementiert sein kann. Dies betrifft insbesondere Funktionen für Netzwerkdienste und die Verwaltung von Dateien, Gruppen und Benutzern.

Die manpage perlfunc stellt alle Funktionen nach Kategorie und außerdem in alphabetischer Ordnung vor, so daß bereits aus der Zuordnung zu einer bestimmten Kategorie ersehen werden kann, ob die entsprechende Funktion für das gewünschte Betriebssystem überhaupt verfügbar ist.

Häufig gebrauchte Funktionen

An dieser Stelle kann keine Übersicht über den gesamten Funktionsumfang von Perl gegeben werden. Stattdessen wird auf die Aufzählung nach Kategorie zu Beginn der manpage perlfunc verwiesen (auch enthalten im Nußschalenbuch auf Seite 86). Die manpage perlfunc enthält außerdem eine vollständige alphabetische Darstellung aller Funktionen mit umfangreichen Beispielen.

Hier werden nur einige wichtige Funktionen erwähnt, die entweder besonders häufig verwendet werden oder besonders idiomatisch für Perl sind, da sie für Perls eigene Datenstrukturen verwendet werden.

Manche Funktionen können sowohl in Listenkontext als auch in skalarem oder Booleschem Kontext angewandt werden, liefern dann aber möglicherweise völlig unterschiedliche Ergebnisse. In solchen Fällen hilft ein Blick in die manpage weiter!

chomp

Sichere Variante von chop. Während chop das letzte Zeichen entfernt, entfernt chomp nur Zeilenumbrüche. Die Vorgabe für den Zeilenumbruch findet sich in der Sondervariablen $/; s. Vordefinierte Variable.

chop

Entfernt das letzte Zeichen einer Zeichenkette. Wird gebraucht, um den Zeilenumbruch bei Eingabezeilen zu entfernen.

while (<>) {
        chop;   # Zeilenumbruch wird von $_ entfernt
        print;  # Zeile wird gedruckt.
        }

die

Ermöglicht den definierten Ausstieg aus einem Programm, wenn ein Fehler vorhersehbar ist. Im folgenden Beispiel wird das Programm beendet, wenn eine Datei (deren Name in $meinfile enthalten ist) nicht gefunden wird.

open(MYHANDLE,$meinfile) or die "$meinfile nicht gefunden.";

eval

Gibt Perl-Code erst zur Laufzeit des Hauptprogramms zur Ausführung, so daß ohne Neustart von Perl Code auf Ausführbarkeit getestet werden kann. Eine praktische Anwendung zeigt das Programm testbed.pl in Kapitel Test-Programm.

exec

Beendet das gerade laufende Perl-Programm und startet an seiner Statt ein anderes. Im Gegensatz hierzu läßt system das gerade laufende Programm weiterleben.

format

Erzeugt eine formatierte Ausgabe. Siehe die detailliertere Erläuterung in Kapitel Formate.

grep

Kann einen Wahrheitswert oder eine Liste mit gefundenen Textfragmenten ausgeben.

@alle_zeilen=<STDIN>;                        # Alle Zeilen der Eingabe
                                        # werden eingelesen
@Kommentare = grep /^#/, @alle_zeilen;  # Gibt nur die Kommentare aus

join

Kombiniert Elemente eines Arrays zu einem Skalar. Erwartet ein Trennsymbol:

@jahreszeiten=(Fruehling,Sommer,Herbst,Winter);
$allevier=join(":",@jahreszeiten);
print $allevier;                # 'Fruehling:Sommer:Herbst:Winter'
join ist der Antagonist von split.

pack

Packt eine Anzahl von Daten in eine binär kodierte Form. Kann beispielsweise für die Umwandlung von Binärzahlen in andere Zahlen- und Zeichenformate verwendet werden:

$zeichen=pack("B8","11110000"); # Grundform: pack TEMPLATE DATEN
print $zeichen;                 # Gibt Zeichen aus, dessen
                                # ASCII-Wert in binärer Darstellung
                                # "11110000" ist.

pop

Gibt den letzten Eintrag eines Arrays (bzw. einer Liste) aus und entfernt diesen gleichzeitig.

@jahreszeiten=(Fruehling,Sommer,Herbst,Winter);
$Xmas=pop @jahreszeiten;
print "$Xmas\n";                                # 'Winter'
print @jahreszeiten;                            # 'FruehlingSommerHerbst'
Das Gegenstück zu pop ist push. Siehe auch shift und unshift, die auf den Anfang eines Arrays wirken.

print

Allgemeine Druckfunktion. Erwartet ein optionales Datei-Handle und eine Liste mit Daten. Liefert als Funktion die Zahl der gedruckten Daten zurück.

printf

Druckt eine formatierte Zeichenkette, wobei eine Formatbeschreibung, gefolgt von einer Datenliste, erwartet wird. Bietet vielfältige Darstellungsoptionen. Die verwandte Funktion sprintf gibt nur Zeichenketten zurück, verwendet aber die gleichen Regeln zur Formatbeschreibung.

push

Hängt Liste an das Ende eines Arrays an:

@jahreszeiten=(Fruehling,Sommer,Herbst);
push @jahreszeiten, "Winter";
print @jahreszeiten;                    # 'FruehlingSommerHerbstWinter'
Gegenteil von pop. Siehe auch shift und unshift, welche auf den Anfang eines Arrays wirken.

reverse

Kehrt die Reihenfolge einer Liste um:

@song=("do","re"","mi");
print @song;                    # 'doremi'
print reverse @song;            # 'miredo'

Um eine Zeichenkette rückwärts auszugeben, muß diese erst in eine Liste konvertiert werden:

print reverse split(//,"Wort"); # 'troW'
                                #
$Wort="Wort";                   # oder, *viel* einfacher:
$troW=reverse($Wort);           # (Man beachte die Klammern!)
print $troW;                    # 'troW'

shift

Gibt den ersten Wert eines Arrays aus und entfernt ihn gleichzeitig aus dem Array. Das ganze Array wird um ein Element kürzer.

@a=(a,b,c,d);
print shift @a;         # 'a'
print @a;               # 'bcd'

Die Umkehroperation ist unshift.

Siehe auch pop unf push, welche auf das Ende eines Arrays wirken.

sort

Sortiert eine Liste. Kann auf Anforderung numerische und Zeichenketten-Daten sortieren; außerdem ist die Definition eigener Sortierroutinen möglich.

splice

Schneidet Stück aus Array aus und fügt optional eine Ersetzung ein. Im folgenden Beispiel wird $kunde durch @vollername ersetzt:

@kundensatz=(Herd,Meier,Kredit);
@vollername=(Gerhard,Hubert,Meier);
splice @kundensatz,1,1,@vollername;
print join(":",@kundensatz);    # 'Herd:Gerhard:Hubert:Meier:Kredit'

split

Erwartet die Angabe einer Trennstelle. Wird benutzt, um einen Skalar (eine Zeichenkette) in mehrere Elemente aufzubrechen, die als einzelne Felder einem Array bzw. einer Liste übergeben werden:

$zeile="Anfang:Mitte:Ende";
@worte=split(/:/,$zeile);
print $worte[1];                # 'Mitte'
Die Ziel-Liste kann auch explizit konstruiert werden:
$nutzer="Mueller:Hans:m";
($nachname,$vorname,$geschlecht)=split(/:/,$nutzer);
print $vorname;                 # 'Hans'

Kehrt die Wirkung von join um.

sprintf

Erzeugt eine formatierte Zeichenkette aus einer Formatangabe und den anschließenden Datenfeldern. Die Definition der Felder ist die gleiche wie bei printf.

system

Betriebssystem-Aufruf. Nachdem system ein Kommando ausgeführt hat, läuft das kommandogebende Programm weiter. im Vergleich dazu ersetzt exec das aufrufende Programm. Vergleiche auch eval.

tr

Übersetzungsfunktion zum Umsetzen von Zeichenmengen:

$name="Bernie";
$name=~tr/A-Z/a-z/;     # Übersetzt alle Großbuchstaben in Kleinbuchstaben
print $name;            # 'bernie'

unshift

Schiebt neues Element an den Anfang einer Liste und gibt die Zahl der Elemente in der neuen Liste zurück:

@Essen=(Milch,Eier);
print unshift @Essen, Butter;   # '3'
print @Essen;                   # 'ButterMilchEier'
Kehrt die Wirkung von shift um. Siehe auch pop unf push, welche auf das Ende einer Liste wirken.

Funktionsdeklarationen

Wie in jeder echten Programmiersprache, so gibt es auch in Perl die Möglichkeit, Funktionen selbst zu definieren. Dies wird mit dem Schlüsselwort sub bewirkt, auf das der Funktionsname und ein Block mit der Definition folgen.

sub MeineFunktion BLOCK

Funktionsdefinitionen sind in mehreren Beispielprogrammen enthalten. Hier wird das Skelett einer Funktion noch einmal vorgeführt:

sub MeineFunktion {
        my $lokale_Variable=$_[0];      # liest den ersten übergebenen
                                        # Parameter aus
        # Aktionen
        $MeineFunktion="Rückgabewerte";    # so kann ein Skalar zurück-
                                        # gegeben werden
}

Anders als Pascal und viele andere Programmiersprachen, die bereits bei der Deklaration einer Funktion der genaue Zahl der Parameter und der zu übergebenden Argumente erwarten und im Sonderfall keines Parameters die Deklaration beispielsweise statt mit FUNCTION mit PROCEDURE einleiten, benötigt Perl keine Angaben über die Zahl der Parameter und Argumente. Diese werden in dem für die Funktion lokalen Array @_ abgelegt, von wo sie ausgelesen werden können. Damit entfällt auch die C-typische Angabe von Prototypen.

2.8 Wörtlicher Text und Begrenzer

Die verschiedenen Anführungszeichen, die bei Perl erlaubt sind, bewirken, ob Variable interpoliert werden oder nicht, oder ob der Text in Anführungszeichen als Kommando aufgefaßt wird.

' '     q//     wörtlich, es wird nicht interpoliert
" "     qq//    wörtlich, es wird interpoliert
` `     qx//    Kommando, es wird interpoliert
( )     qw//    Wortliste, es wird nicht interpoliert
/ /     m//     Mustervergleich mit Interpolation
s///    s///    Ersetzungsoperation mit Interpolation
y///    tr///   Übersetzungsoperation zwischen
                Zeichenmengen ohne Interpolation

Grundsätzlich werden wörtliche Werte, die an Variablen übergeben werden, in einfache oder doppelte Anführungszeichen eingeschlossen. Davon hängt dann ab, ob eventuelle Variable interpretiert werden oder wörtlich eingesetzt werden:


$Wert="DM $betrag";     # $betrag wird mit seinem Wert eingesetzt
$Wert='DM $betrag';     # $betrag wird als '$betrag' eingesetzt; nicht gewollt.

Unter bestimmten Umständen können wörtliche Werte auch ohne Anführungszeichen übergeben werden; Perl bezeichnet dies als bare words (nackte Wörter):


$Wort=Silberling;       # Nur erlaubt, wenn keine Sonderzeichen
                        # enthalten sind; gilt auch für Arrays
@Pronomen=(er, sie, es) # 

Zahlen bilden eine Sonderform der nackten Wörter, sie können immer ohne Begrenzer übergeben werden:


$betrag=4000;   # Kein Begrenzer nötig

Wenn die auf q lautenden Formen als Begrenzer genommen werden, kann sich Text auch über mehrere Zeilen erstrecken, was besonders für CGI-Programme sehr praktisch ist. Die Formen mit q akzeptieren alle Klammerarten, die der ASCII-Zeichensatz bietet, als Begrenzer.

2.9 Reguläre Ausdrücke

Ein Regulärer Ausdruck ist ein nach bestimmten Regeln geformtes Gebilde, dessen Auswertung einen oder mehrere Zeichenketten ergibt, die dann mit existenten Zeichenketten verglichen werden können.

Exakter gesprochen, handelt es sich bei Regulären Ausdrücken um Ausdrücke, mit denen sich Wörter nach Regeln von Sprachen des Typs III bilden lassen.

Alle Regulären Ausdrücke müssen von ihrer Umgebung abgegrenzt werden. Dazu wird in Perl meistens der Schrägstrich benutzt, obwohl dies nicht zwingend vorgeschrieben ist.

Reguläre Ausdrücke genügen daher zumindest der folgenden Form:

# /RA/                          # Ein Regulärer Ausdruck wird im
                                # Regelfall in Schrägstriche
                                # eingeschlossen.

if (/RA/) { print ; }           # Druckt die in $_ gespeicherte
                                # Zeichenkette dann, wenn sie RA
                                # enthält.

Reguläre Ausdrücke werden aber auch häufig für bedingte Such- und Ersetzungsoperationen eingesetzt. Die Notation s/alt/neu/ ersetzt jedes Vorkommen des Ausdrucks alt gegen den Ausdruck neu.

Der einfachste RA (englisch RE, Regular Expression) wird durch Zeichen gebildet, die nicht anders interpretiert werden können als in ihrer normalen Bedeutung.

Daher ist /RA/ ein Regulärer Ausdruck, mit dem sich die Buchstabenfolge RA in einem gegebenen Text finden läßt. Dies kann die Textzeile RA ebenso sein wie die Zeile Wir trinken alle heiße RAMA mit Marshmallows.

Hingegen wird die Buchstabenfolge ra in Brahma nicht gefunden, da diese ja nicht mit RA identisch ist.

Es muß daher Wege geben, Reguläre Ausdrücke zu erweitern. Dazu bedient man sich sogenannter Metazeichen, die nicht für sich stehen, sondern etwas anderes bedeuten. Die wichtigsten Metazeichen werden nun vorgestellt:

.

Der Punkt steht für jedes beliebige Zeichen außer dem Zeilenende.

$

Das Dollarzeichen verankert den Suchausdruck am Zeilenende.

^

Der Circonflex verankert den Suchausdruck am Zeilenanfang.

[ ]

In eckigen Klammern wird eine Zeichenmenge erfaßt, die an einer Stelle des RAs erwartet wird. [abc] bedeutet, daß an einer Stelle ein a, ein b oder ein c stehen darf.

In eckigen Klammern negiert der Circonflex als erstes Zeichen die Menge. [^abc] bedeutet also, daß an einer Stelle weder ein a, ein b oder ein c stehen darf, dafür aber alle anderen Buchstaben.

In eckigen Klammern erzeugt der Bindestrich - eine Liste. [a-e] erfaßt also alle Buchstaben von a bis e. Analog gilt auch hier die Negierungsregel mit ^. Der Ausdruck [^a-e] findet also alle Zeichen außer den Buchstaben von a bis e.

?

Das Fragezeichen gibt an, daß das vorausgegangene Atom mindestens keinmal, aber auch einmal erscheinen kann.

+

Das Pluszeichen gibt an, daß das vorausgegangene Atom mindestens einmal, aber auch mehrfach erscheinen kann.

*

Der Stern gibt an, daß das vorausgegangene Atom beliebig oft erscheinen kann. Beliebig oft schließt auch keinmal ein. Daher wird mit dem Ausdruck /ab*c/ neben abc und abbbbbbc auch ac gefunden.

{n,m}

Alternativ kann in geschweiften Klammern auch ein Bereich angegeben werden, wobei n für die kleinste Zahl, m hingegen für die größte erlaubte Zahl des Vorkommens steht.

|

Der Vertikalstrich reiht mehrere gleichberechtigte Suchausdrücke aneinander. Der Ausdruck /auf|oder|ab/ findet die Zeichenketten auf, oder und ab. Das heißt, daß natürlich nicht nur die gleichlautenden Wörter, sondern auch Lauf, Schabefleisch und Modernes Leben gefunden werden, um nur ein paar Beispiele zu nennen.

()

Einfache Klammern dienen zur Zwischenspeicherung eines Ausdrucks, der später weiterverwendet werden kann. Auf den solchermaßen zwischengespeicherten Ausdruck kann anschließend bei einer Ersetzungsoperation zurückgegriffen werden.

\

Der rückwärts geneigte Schrägstrich kehrt die Wirkung von Zeichen um. Metazeichen werden nun als einfache Zeichen interpretiert, während bisherige einfache Zeichen nun neue Bedeutungen annehmen.

$1..9

Mit Dollar-Zahl oder rückwärts geneigtem Schrägstrich wird ein in Klammern eingeschlossener Teilausdruck referenziert. Mit ,,Dollar-Zahl'' läßt sich der Ausdruck auch außerhalb der Operation weiter referenzieren.

$wort="Wort";
$wort =~ s/(o)/\1-\1/;
print $wort;            # Gibt "Wo-ort" aus.
$wort="Wort";
$wort =~ s/(o)/$1-$1/;
print $1;               # Gibt "o" aus.

\s

Mit \s kann man Wortzwischenräume finden, da \s als [ \t\n]+ definiert ist.

\w

Mit \w kann man Wörter finden, da \w als [A-Za-z]+ definiert ist.

Es gibt darüberhinaus noch eine Reihe weiterer Buchstaben mit Sonderfunktion, die in Programming Perl auf Seite 64 ff. und in der manpage perlre näher erläutert werden.

Substitutionsoperationen der Art s/alt/neu/ erlauben die Angabe von Optionen, deren wichtigste hier aufgeführt werden. Mehrere Optionen dürfen miteinander kombiniert werden.

g

Diese Option gibt an, daß eine Substitution für alle Fundstellen innerhalb der Zeichenkette erfolgen soll:

$wort="Schlammschlacht";
$wort=~s/la/ru/;
print $wort;            # "Schrummschlacht" erscheint
$wort="Schlammschlacht";
$wort=~s/la/ru/g;
print $wort;            # "Schrummschrucht" erscheint

e

Diese Option gibt an, daß die rechte Seite des Substitutionsausdrucks evaluiert werden soll. Es ist daher möglich, auf der rechten Seite eine Funktion oder eine Variablenabfrage in den Ersetzungsstring zu schreiben:

s/(.)/$meinhash{$1}/eg; # Ersetzt jedes Zeichen durch den Wert, der
                        # im Hash %meinhash gefunden wird, wobei
                        # das Zeichen als Schlüssel fungiert

x

Diese Option gibt an, daß der Substitutionsausdruck zwecks leichterer Lesbarkeit durch Leerstellen, Zeilenumbrüche und Kommentare unterbrochen werden darf:

s/([0-9]{5})[ \t]?      # Postleitzahl, dann Leerraum
  ([A-ZÄÖÜ][a-zäöü]+      # Städtename
  [ A-Zäöüa-zäöü]*)       # Zusatz (z.B. "im Breisgau")
  /PLZ: \1Ort: \2/x;    # Ersetzungsausdruck

Die eben angegebene Form ist inhaltlich identisch mit der folgenden, aber mit Sicherheit einfacher zu verstehen:

s/([0-9]{5})[ \t]?([A-ZÄÖÜ][a-zäöü]+[ A-Zäöüa-zäöü]*)/PLZ: \1Ort: \2/;

2.10 Formate (Ausgabeschablonen)

Perl ist auch eine Sprache zur Erzeugung strukturierter Datenübersichten (reports auf neudeutsch), wie es im Namen Perl (Practical Extraction and Report Language) ja schon gesagt wird.

Es ist natürlich möglich, mit sprintf und möglichen Hilfskonstruktionen ansprechend formatierte Datenbankauszüge zu erstellen, noch einfacher ist aber die Verwendung des Perlschen Formatgenerators.

Formatdeklarationen

Ein Format wird ähnlich wie eine benutzerdefinierte Funktion deklariert. Auf das Schlüsselwort format folgen der optionale Name des Formats und ein Gleichheitszeichen. In der nächsten Zeile kommt die erste Zeilenschablone, darauf folgen die Variablen, die nach dieser Schablone ausgegeben werden sollen. Die Formatdeklaration wird durch einen Punkt zu Zeilenanfang abgeschlossen.

Formate können überall im Quelltext stehen und sind an keine bestimmte Ordnung in Bezug auf die Hauptroutinen des Programms gebunden.

Aufgerufen wird ein Format durch das Befehlswort write, dem optional der Formatname nachgestellt wird. Wenn der Formatname in der Deklaration und im Aufruf weggelassen wird, so wird die Standardausgabe als Voreinstellung angenommen.

Das folgende Codefragment zeigt eine Iteration über das Array @worte, dessen einzelne Elemente rechtsbündig ausgegeben werden. Eine praktische Anwendung ist in Kapitel Rückläufige Sortierung beschrieben.

foreach $wort (@worte) {
        write FORMATNAME
}

format FORMATNAME =
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$wort
.

Text in Formaten kann rechtsbündig, linksbündig, zentriert, und über mehrere Zeilen umgebrochen ausgegeben werden. Die dafür nötigen Deklarationen und Befehle sind alle in der manpage perlform erklärt.


Weiter Zurück Inhalt