Wie jede gute Programmiersprache können in Perl eigene Funktionen programmiert werden. Man nennt sie in Perl Subroutinen.
Subroutinen (kurz: Subs) sind wiederverwendbare Code-Teile.
Sie können irgendwo im Programm platziert werden. Normalerweise wird man sie an den Anfang oder ans Ende des Programmes stellen.
Beispiel:
sub mysubroutine
{
print "Dies ist eine langweilige Subroutine.\n";
print "Sie macht immer das gleiche!\n";
}
Alle folgenden Anweisungen rufen diese Subroutine auf. Das Kaufmannsund &
kann am Anfang des Namens stehen, muss aber nicht.
&mysubroutine; # Aufruf ohne Parameter
&mysubroutine($_); # Aufruf mit einem Parameter
&mysubroutine(1+2, $_); # Aufruf mit zwei Parametern
Im Allgemeinen gelten folgende Regeln für den Unterprogrammaufruf:
NAME(LIST); # & ist fakultativ mit Klammern
NAME LIST; # Klammern sind fakultativ falls vordefiniert oder importiert
&NAME; # übergibt der Subroutine aktuellen @_
Im obigen Fall wurden die Parameter akzeptiert aber nicht verwendet. Mit dem Aufruf
einer Subroutine werden alle übergebenen Parameter im Spezialarray @_
gespeichert.
Diese Variable hat nichts zu tun mit der Spezialvariablen $_
. @_
ist ein
Array, $_
ist eine skalare Variable. Die folgende Subroutine gibt die Liste der
Parameter aus, mit welcher sie aufgerufen wurde:
sub printargs
{
print "@_\n";
}
&printargs("perly", "king"); # Example prints "perly king"
&printargs("frog", "and", "toad"); # Prints "frog and toad"
Wie bei jedem anderen Array, können die einzelnen Elemente von @_
mit eckigen
Klammern zugegriffen werden:
sub printfirsttwo
{
print "Der erste Parameter war $_[0]\n";
print "und $_[1] war der zweite\n";
}
Wir betonen noch einmal das $_[0]
und $_[1]
nichts zu tun haben mit der
Spezialvariablen $_
und das beides gleichzeitig benützt werden darf, ohne
Namenskollisionen befürchten zu müssen.
Das Resultat einer Subroutine ist immer das Resultat des letzten evaluierten Ausdruckes. Diese Subroutine berechnet das Maximum von zwei gegebenen Eingabeparameter:
sub maximum
{
if ($_[0] > $_[1]) {
$_[0];
} else {
$_[1];
}
}
Der Aufruf sieht so aus:
$biggest = &maximum(37, 24); # $biggest ist 37
Die Subroutine printfirsttwo
gibt ebenfalls einen Wert zurück, und zwar ist es
1. Die letzte Evaluation dieser Subroutine war die print
-Anweisung. Das Resultat
einer erfolgreichen print
-Anweisung ist immer 1.
Um sichtbar zu machen, dass etwas zurückgegeben werden soll, ist es empfehlenswert, die return
-Funktion zu verwenden.
Für das vorherige Beispiel sieht das dann so aus:
sub maximum
{
if ($_[0] > $_[1]) {
return $_[0];
} else {
return $_[1];
}
}
Die Variable @_
ist lokal zur aktuellen Subroutine. Um Namenskollisionen zu
vermeiden, können auch andere Variablen lokal gemacht werden. Dazu verwenden wir die
Funktionen my oder local.
In der Regel möchte man die Elemente von @_
einer eigenen lokalen Variablen speichern, etwa um die Lesbarkeit zu verbessern.
Die folgende Subroutine testet, ob ein String ein Substring eines anderen ist, ohne die Leerzeichen zu berücksichtigen:
sub inside
{
my ($a, $b); # Erzeuge lokale Variablen
($a, $b) = ($_[0], $_[1]); # Parameter zuordnen
$a =~ s/ //g; # Leerzeichen aus lokaler
$b =~ s/ //g; # Variable löschen
($a =~ /$b/ || $b =~ /$a/); # Ist $b in $a
# oder $a in $b?
}
&inside("lemon", "dole money"); # true
Falls mehr als eine Variable mit my
deklariert werden soll, müssen sie in
Klammern angegeben werden (my
ist eine Funktion!). Wir können das Ganze auch noch
ein wenig eleganter schreiben, indem wir die ersten beiden Zeilen zusammenfassen:
my ($a, $b) = @_;
local
my
ist die neuere (ab Perl 5) und effizientere Art, um lokale Variablen zu deklarieren.
Der Unterschied zu local
liegt in wichtigen Feinheiten.
local
erzeugt einen temporären Wert für eine globale Variable (dynamic scoping), wohingegen my
eine echte lokale Variable deklariert (lexical scoping), welche nur im umgebenden Block, Subroutine (oder eval
) bekannt ist.
Die Syntax ist bei beiden gleich.
Eine Einschränkung gibt es bei den Variablennamen: Mit my
sind nur alphanumerische Zeichen erlaubt.
Um Spezialvariablen, wie zB. $\
lokal zu ändern, muss local
verwendet werden.
Mache aus der for
-Schleife der letzten Übung eine Subroutine mit zwei Parametern.
Der erste ist der Suchstring, der zweite der Array aus den Teilstücken des Textes.
Innerhalb der Subroutine sollen alle Variablen lokal sein (mit my
).
Rufe diese Subroutine im Hauptprogramm auf.