TOC PREV Übungen NEXT INDEX

4 Subroutinen

Systemfunktionen und benutzerdefinierte Funktionen

Wir haben bereits einige eingebaute Systemfunktionen kennengelernt; unter anderem chomp, reverse, print und so weiter. Wie in anderen Sprachen, ist es auch in Perl möglich, Subroutinen, also benutzerdefinierte Funktionen zu erstellen.1 Hierdurch kann dasselbe Codestück in einem Programm mehrmals verwendet werden.2

Der Name einer Subroutine besteht ebenfalls aus einem Perl-Identifier (Buchstaben, Zahlen und Unterstrichen, aber keine Ziffer am Anfang), dem ein Ampersand-Zeichen (&, »Kaufmanns-Und«) vorangestellt wird. Dieses Zeichen kann in bestimmten Fällen auch weggelassen werden. Die Regel dazu finden Sie am Ende dieses Kapitels. Bis auf weiteres werden wir das Zeichen immer verwenden, sofern es nicht ausdrücklich verboten ist. Dadurch sind Sie immer auf der sicheren Seite. Und selbstverständlich sagen wir Ihnen auch, an welchen Stellen es verboten ist.

Ebenso wie Skalare und Arrays haben auch Subroutinen ihren eigenen Namensraum, so daß Perl nicht durcheinanderkommt, wenn Sie eine Subroutine mit dem Namen &fred und einen Skalar $fred nebeneinander in Ihrem Programm benutzen wollen - auch wenn es dafür unter normalen Umständen eigentlich keinen Grund gibt.

Subroutinen definieren

Um Ihre eigene Subroutine zu definieren, benutzen Sie das Schlüsselwort sub, gefolgt vom Namen der Subroutine (ohne das Kaufmanns-Und). Hierauf folgt der eingerückte3 Codeblock (in geschweiften Klammern), den wir den Körper der Subroutine nennen:

 sub marine {
   $n += 1;  # globale Variable $n
   print "Hallo, Taucher Nummer $n!\n";
 }

Subroutinen können Sie an jeder beliebigen Stelle in Ihrem Programm definieren. Programmierer, die sich mit Sprachen wie C oder Pascal auskennen, schreiben ihre Subroutinen vermutlich lieber an den Anfang ihrer Programme; andere wiederum schreiben die Subroutinen lieber an das Ende, so daß der Hauptteil des Programms am Anfang steht. Die Wahl ist Ihnen selbst überlassen. Sie brauchen Ihre Subroutinen jedenfalls nicht vorzudeklarieren.4

Subroutinen-Definitionen sind global, das heißt, sie gelten in Ihrem gesamtem Programm; ohne irgendwelche schlauen Tricks anzuwenden sind private Subroutinen nicht möglich.5 Wenn Sie also in einem Programm zwei Subroutinen mit dem gleichen Namen definieren, so überschreibt die später definierte die frühere.6 Dies wird in der Regel als schlechte Form angesehen, manchmal auch als Zeichen der Verwirrung bei dem Wartungsprogrammierer.

Wie Sie in unserem vorigen Beispiel vielleicht schon bemerkt haben, ist es möglich, globale Variablen im Körper einer Subroutine zu benutzen. Wenn wir genau sind, waren bisher alle Variablen, die wir gesehen haben, global, d. h. von jedem Teil Ihres Programms aus zugänglich. Das verschreckt natürlich die Sprachpuristen, aber das Perl-Entwicklungsteam hat sich zusammengerottet und sie mit Schimpf und Schande aus der Stadt verjagt. Im Abschnitt »Private Variablen in Subroutinen« weiter hinten in diesem Kapitel zeigen wir Ihnen, wie Sie Variablen anlegen können, die nur in Ihrer Subroutine gültig sind.

Subroutinen aufrufen

Innerhalb eines Ausdrucks rufen Sie eine Subroutine auf, indem Sie einfach ihren Namen (mit vorgestelltem Kaufmanns-Und) verwenden:7

 &marine;  # sagt Hallo, Taucher Nummer 1!
 &marine;  # sagt Hallo, Taucher Nummer 2!
 &marine;  # sagt Hallo, Taucher Nummer 3!
 &marine;  # sagt Hallo, Taucher Nummer 4!

Rückgabewerte

Subroutinen werden immer als Teil eines Ausdrucks aufgerufen, selbst wenn das Ergebnis des Ausdrucks nicht benutzt wird. Als wir vorhin die Subroutine &marine aufgerufen haben, haben wir den Wert des Ausdrucks berechnet, das Ergebnis aber wieder verworfen.

Oft ist es aber so, daß wir beim Aufruf einer Subroutine auch das Ergebnis verwenden wollen. Wir verwenden also den Rückgabewert einer Subroutine. In Perl haben alle Subroutinen einen Rückgabewert - es macht hierbei keinen Unterschied, ob explizit ein Wert zurückgegeben wird oder nicht. Dennoch hat nicht jede Subroutine auch einen nützlichen Rückgabewert.

Da alle Perl-Subroutinen so aufgerufen werden können, daß sie einen Wert zurückgeben, wäre es reine Verschwendung, wenn dafür jedesmal eine spezielle Syntax benutzt werden müßte. Deshalb hat Larry die Sache vereinfacht: Wird eine Subroutine aufgerufen, werden die Werte automatisch im Hintergrund mitberechnet. Der Wert, der zuletzt in der Subroutine berechnet wird, ist automatisch auch der Rückgabewert.

Lassen Sie uns zum Beispiel einmal die folgende Subroutine ansehen:

 sub summe_von_fred_und_barney {
 	   print "Sie haben die summe_von_fred_und_barney-Subroutine
         	 aufgerufen.\n";
   $fred + $barney;  # Dies ist der Rückgabewert.
 }

Der letzte Ausdruck, der im Körper der Subroutine ausgewertet wurde, berechnet die Summe von $fred und $barney. Also ist die Summe von $fred und $barney auch der Rückgabewert der Subroutine. Hier sehen Sie die Subroutine in Aktion:

 $fred   = 3;
 $barney = 4;
 $c      = &summe_von_fred_und_barney;     # $c erhält den Wert 7
 print "\$c hat den Wert $c.\n";
 $d      = 3 * &summe_von_fred_und_barney; # $d erhält den Wert 21
 print "\$d hat den Wert $d.\n";

Dieser Code erzeugt die folgenden Ausgaben:

 Sie haben die summe_von_fred_und_barney-Subroutine aufgerufen.
 $c hat den Wert 7.
 Sie haben die summe_von_fred_und_barney-Subroutine aufgerufen.
 $d hat den Wert 21.

Hierbei ist die print-Anweisung nur eine Hilfe zum Debuggen, damit Sie sehen, daß wir die Subroutine tatsächlich aufgerufen haben. Ist Ihr Programm einmal fertiggestellt, würden Sie diese Anweisungen wieder entfernen. Aber nehmen wir einmal an, Sie hätten am Ende des Codes eine weitere Zeile eingefügt:

 sub summe_von_fred_und_barney {
 	  print "Sie haben die summe_von_fred_und_barney-Subroutine
 	        aufgerufen.\n";
   $fred + $barney;  # Dies ist jetzt nicht mehr der Rückgabewert!
   print "Juhu! Jetzt bin ich der Rueckgabewert!\n";  # Hoppla!
 }

In diesem Beispiel ist der letzte ausgewertete Ausdruck nicht mehr die Addition, sondern die print-Anweisung. Der Rückgabewert von print ist normalerweise 1, was einfach bedeutet »die Ausgabe war erfolgreich«.8 Das ist jedoch nicht der Rückgabewert, den wir eigentlich haben wollten. Seien Sie also vorsichtig, wenn Sie eine Subroutine um zusätzlichen Code ergänzen, damit der letzte ausgewertete Ausdruck auch tatsächlich den gewünschten Wert zurückgibt.

Und was ist jetzt mit der Summe aus $fred und $barney in der Subroutine passiert? Wir haben den Wert nirgendwo abgelegt, also hat Perl ihn wieder verworfen. Hätten Sie die Warnungen eingeschaltet, so hätte Perl Sie höchstwahrscheinlich davor gewarnt, daß hier ein »useless use of addition in a void context« (eine unnütze Verwendung einer Addition ohne Zusammenhang) vorliegt. Dies ist nur eine andere Art zu sagen, daß die Summe in keiner Variable gespeichert oder von einer anderen Funktion benutzt wird.

»Der letzte ausgewertete Ausdruck« heißt hier tatsächlich: der letzte Ausdruck, der ausgewertet wurde, und nicht die letzte Zeile Text. Diese Subroutine gibt den größeren der beiden Werte $fred oder $barney zurück:

 sub ist_fred_oder_barney_groesser {
   if ($fred > $barney) {
     $fred;
   } else {
     $barney;
   }
 }

Der letzte ausgewertete Ausdruck ist hier entweder $fred oder $barney. Je nachdem, welcher Wert größer ist, ist also $fred oder $barney der Rückgabewert. Welcher von beiden das sein wird, können wir erst sagen, wenn wir wissen, welche Variablen $fred und $barney zur Laufzeit des Programms haben werden.

Wird eine Subroutine im Listenkontext9 aufgerufen, so kann sie auch eine Liste von Werten zurückgeben. Nehmen wir an, Sie wollten sich einen Zahlenbereich (wie ihn der Bereichsoperator »..« erzeugt) ausgeben lassen. Hierbei soll jedoch nicht nur aufwärts, sondern auch abwärts gezählt werden können. Der Bereichsoperator funktioniert nur »aufwärts«, aber das können wir leicht beheben:

 sub liste_von_fred_bis_barney {
   if ($fred < $barney) {
     # Aufwärts von $fred bis $barney zählen
     $fred..$barney;
   } else {
     # Abwärts von $barney bis $fred zählen
     reverse $barney..$fred;
   }
 }
 $fred   = 11;
 $barney = 6;
 @c      = &liste_von_fred_bis_barney; # @c enthält nun (11, 10, 9,
                                       # 8, 7, 6)

In diesem Fall gibt uns der Bereichsoperator die Liste der Zahlen von 6 bis 11, die dann von reverse umgedreht wird, so daß sie wie gewünscht von $fred (11) bis $barney (6) alle Zahlen in absteigender Reihenfolge ausgibt.

Dies sind alles noch recht triviale Beispiele. Das Ganze wird besser, sobald wir in der Lage sind, die Subroutine bei jedem Aufruf mit neuen Werten aufzurufen, anstatt uns auf globale Variablen verlassen zu müssen. Wie der Zufall es will, ist genau das das Thema des kommenden Abschnitts.

Argumente

Die Subroutine ist_fred_oder_barney_groesser wäre noch viel nützlicher, wenn wir nicht gezwungen wären, die globalen Variablen $fred und $barney zu verwenden. Wollten Sie zum Beispiel auch den größeren Wert von $wilma und $betty ermitteln, so müßten Sie diese erst in die Variablen $fred und $barney kopieren, bevor die Subroutine für diesen Fall benutzbar wäre. Stünde in diesen Variablen nun bereits etwas anderes Nützliches, müßten wir diese Werte vor der Operation ihrerseits erst sichern, zum Beispiel in $fred_sichern und $barney_sichern. Am Ende der Subroutine müßten wir dann die ursprünglichen Werte auch noch wieder zurückkopieren.

Zum Glück gibt es in Perl Subroutinen-Argumente. Um eine Liste von Argumenten an die Subroutine zu übergeben, schreiben Sie diese einfach in runden Klammern hinter den Aufruf der Subroutine, wie hier gezeigt:

 $n = &max(10, 15);  # Subroutine wird mit zwei Argumenten aufgerufen

Die Liste wird an die Subroutine übergeben, d. h. die Subroutine kann die Argumente nun ganz nach Bedarf bearbeiten. Selbstverständlich muß auch die Parameterliste (ein anderer Name für die Liste der Argumente) in einer Variablen gespeichert werden. Perl erledigt dies automatisch mit Hilfe der speziellen Arrayvariablen @_, die für die Dauer der Subroutine die aufrufenden Argumente enthält.

Der erste Parameter, der auf diese Weise an die Subroutine übergeben wurde, ist folglich in $_[0] zu finden, der zweite in $_[1] und so weiter. An dieser Stelle ein wichtiger Hinweis: Diese Variablen haben mit der Variablen $_ so wenig zu tun, wie $dino[3] (ein Element aus dem Array @dino) mit der Variablen $dino zu tun hat. Die Parameterliste muß für die Verwendung in der Subroutine nun einmal in einer Arrayvariablen gespeichert werden und Perl verwendet dafür das Array @_.

Jetzt könnten Sie eine Subroutine mit dem Namen &max schreiben, die so ähnlich aussieht wie &ist_fred_groesser_als_barney. Anstelle von $a könnten Sie nun den ersten Subroutinen-Parameter einsetzen ($_[0]) und anstelle von $b den zweiten Subroutinen-Parameter ($_[1]). Am Schluß könnten Sie also etwas wie das Folgende schreiben:

 sub max {
   # Vergleichen Sie dies mit &ist_fred_oder_barney_groesser
   if ($_[0] > $_[1]) { 
     $_[0];
   } else {
     $_[1];
   }
 }

Wie gesagt, Sie könnten das so machen. Mit den ganzen Indizes sieht das jedoch ziemlich häßlich aus; zudem ist es schwer zu lesen, zu schreiben und zu debuggen. Wir werden gleich eine bessere Methode sehen.

Ein anderes Problem besteht darin, daß der Name &max zwar schön kurz ist, uns aber nicht daran erinnert, daß diese Subroutine nur mit exakt zwei Parametern korrekt funktioniert.

 $n = &max(10, 15, 27);  # Hoppla!

Weitere Parameter werden ignoriert, da sich die Subroutine das dritte Argument, $_[2], nie ansieht. Perl ist es egal, wie viele Werte Sie übergeben. Im letzeren Fall wird bei dem Versuch, hinter das Ende von @_ zu schauen, einfach undef verwendet, genau wie bei jedem anderen Array auch. Weiter hinten in diesem Kapitel zeigen wir, wie Sie die &max-Subroutine so umschreiben können, daß eine beliebige Anzahl von Parametern übergeben werden kann.

Die Variable @_ existiert in der Subroutine lokal.10 Gibt es also auch eine globale Variable @_, so wird ihr Wert vor dem Aufruf der Subroutine gesichert. Ist die Subroutine beendet, wird der ursprüngliche Wert wiederhergestellt.11 Dies hat zur Folge, daß eine Subroutine Argumente an eine andere Subroutine übergeben kann, ohne dabei die Werte ihrer eigenen @_-Variable zu verlieren. Bei verschachtelten Subroutinen-Aufrufen bekommt so jede Subroutine ihr eigenes @_-Array zugeteilt. Dies funktioniert sogar dann, wenn sich die Subroutine rekursiv selbst aufruft.

Private Variablen in Subroutinen

Wenn Perl uns für jeden Aufruf ein neues @_ geben kann, ist dies auch mit Variablen möglich? Aber sicher!

Standardmäßig sind alle Variablen in Ihrem Programm als globale Variablen angelegt; d. h. sie sind von jedem Teil des Programms aus zugänglich. Mit dem my-Operator können Sie aber jederzeit auch private bzw. lexikalische Variablen anlegen. Zum Beispiel:

 sub max {
   my($a, $b); # neue, private Variablen für diesen Block anlegen
   ($a, $b) = @_; # die Parameter benennen
   if ($a > $b) { $a } else { $b }
 }

Diese Variablen sind nun privat beziehungsweise besitzen einen auf den umschließenden Block begrenzten Geltungsbereich; andere Variablen außerhalb des Blocks, die auch $a oder $b heißen, werden hiervon nicht beeinflußt. Dies funktioniert ebenso in der anderen Richtung - kein Code kann diese privaten Variablen versehentlich oder absichtlich12 von außen verändern. Wir könnten diese Subroutine also in ein beliebiges Perl-Programm auf dieser Welt einbauen und dabei sicher sein, daß keine anderen Variablen in diesem Programm, die zufällig auch $a oder $b heißen, davon durcheinandergebracht werden.13

Es ist vielleicht noch einen Hinweis wert, daß innerhalb eines if-Blocks nach dem Ausdruck, der den Rückgabewert definiert, kein Semikolon stehen muß. Auch wenn dies innerhalb eines Blocks möglich ist, wird das Semikolon nur dann weggelassen, wenn der Code, wie in den vorigen Beispielen, so einfach ist, daß der Block auf einer einzelnen Zeile Platz findet.

Die Subroutine aus dem vorigen Beispiel läßt sich sogar noch weiter vereinfachen. Ist Ihnen aufgefallen, daß die Liste ($a, $b) zweimal erwähnt wird? Dabei läßt sich der my-Operator auch auf eine in runden Klammern stehende Liste anwenden. Daher ist es üblicher, die beiden ersten Anweisungen in der Subroutine miteinander zu kombinieren:

 my($a, $b) = @_;  # Subroutinen-Parameter benennen und
                   # "privatisieren"

Diese Anweisung erzeugt gleichzeitig zwei private Variablen und weist ihnen Werte zu. Hierdurch haben die Parameter nun die leichter zu benutzenden Namen $a und $b. Fast jede Subroutine beginnt mit einer Zeile wie dieser, in der die Parameter benannt werden. Wenn Sie diese Zeile in Zukunft sehen, wissen Sie also, daß die Subroutine zwei skalare Parameter erwartet, die innerhalb der Subroutine $a und $b heißen.

Der local-Operator

Den folgenden Abschnitt können Sie als eine große Fußnote ansehen. Da wir aber leider keine Fußnoten mit Fußnoten versehen können, haben wir das Folgende im Haupttext belassen. Beim ersten Lesen können Sie diesen Abschnitt überspringen und mit dem Abschnitt »Parameterlisten mit variabler Länge« weitermachen. Sie werden diesen Abschnitt weder für die Übungen am Ende des Kapitels noch für das Schreiben von Perl-Code brauchen (jedenfalls für eine lange Zeit). In Kursen gibt es aber immer jemanden, der fragt: »Was hat es denn jetzt mit diesem local-Dingsda auf sich, das ich in manchen Perl-Programmen finden kann?« Zu Ihrer persönlichen Freude und Erbauung haben wir diesen Teil, der in unseren Kursen normalerweise als Randbemerkung vorkommt, hier mit aufgenommen.

Besonders in älterem Code oder älteren Perl-Büchern werden Sie gelegentlich den local-Operator an der Stelle von my benutzt sehen. Meistens sieht der Code so aus, wie bei my:

 sub max {
   local($a, $b) = @_;  # sieht my ziemlich ähnlich
   if ($a > $b) { $a } else { $b }
 }

Hierbei trägt local jedoch einen falschen oder zumindest einen irreführenden Namen. Unser Freund Chip Saltzenberg hat einmal gesagt, wenn er jemals die Chance bekäme, mit einer Zeitmaschine ins Jahr 1986 zurückzureisen und Larry einen guten Ratschlag zu geben, so würde er Larry darum bitten, local besser »save« zu nennen.14 Dies liegt daran, daß local den Wert einer globalen Variablen sichert und automatisch wiederherstellt. (Genau. Diese sogenannten »lokalen« Variablen sind eigentlich global!) Hierbei handelt es sich um den gleichen Mechanismus, den wir schon zweimal gesehen haben: einmal bei der Kontrollvariablen für die foreach-Schleife und einmal bei dem Array für Subroutinen-Parameter.

Als nächstes legt local eine Kopie des Wertes der Variablen an einem geheimen Ort (dem »Stack«) an. Während der Wert gesichert ist, ist es weder möglich, auf ihn zuzugreifen, noch ihn zu ändern oder zu löschen.15 Ist der Wert gesichert, weist local der Variablen einen leeren Wert zu (undef für Skalare oder eine leere Liste für Arrays) beziehungsweise den Wert, den Sie innerhalb der Subroutine definiert haben. Nach dem Ende der Subroutine16 stellt Perl den ursprünglichen Wert automatisch wieder her. Man kann also sagen, daß local sich die Variable eigentlich nur ausgeliehen hat und diese (hoffentlich) am Ende wieder zurückgeben wird, bevor jemand etwas gemerkt hat.

Der Unterschied zwischen local und my

Was passiert aber nun, wenn die Subroutine eine weitere Subroutine aufruft, und zwar eine, die merkt, daß die Variable nur von local ausgeliehen war? Zum Beispiel:

 $buero = "global";  # globale Variable $buero
 &sagwas(  ); # gibt "global" aus, greift direkt auf $buero zu
 
 &fred(  );   # gibt "fred" aus, dynamischer Geltungsbereich, da die
            # lokale Variable $buero in &fred die globale Variable
            # $buero verdeckt
 
 &barney(  ); # gibt "global" aus, lexikalischer Geltungsbereich; die
            # Variable $buero in &barney ist nur innerhalb des sie
            # umgebenden Blocks sichtbar
 
 sub sagwas { print "$buero\n"; }
            # gibt die gegenwärtig sichtbare Variable $buero aus
 sub fred   { local($buero) = "Fred";   &sagwas(  ); }
 sub barney { my   ($buero) = "Barney"; &sagwas(  ); }

Als erstes rufen wir die Subroutine &sagwas auf, die uns mitteilt, welche Version von $buero sie sieht - in diesem Fall die globale Variable $buero. Dies ist der Normalfall.

Als nächstes rufen wir die Subroutine &fred auf. Diese besitzt ihre eigene, lokale Version von $buero, wodurch sich folglich auch das Verhalten der Subroutine &sagwas ändert. Nun wird der Wert ausgegeben, den &freds Version von $buero enthält. Ohne den restlichen Code zu kennen, können wir nicht wissen, ob dies ist, was Fred tatsächlich wollte.

Barney dagegen ist ein bißchen schlauer und ein bißchen kürzer. Daher benutzt er den kürzeren (und auch ein bißchen schlaueren) Operator my. Auf Barneys private Variable $buero kann zudem von außerhalb der Subroutine nicht zugegriffen werden. Die Subroutine &sagwas verhält sich also wieder normal; für sie ist allein die globale Variable $buero sichtbar. Barneys Vorgehensweise hat also das Verhalten von &sagwas nicht verändert, was Programmierer meistens eher mögen und auch erwarten würden.

Wenn diese beiden Operatoren Sie nun etwas durcheinandergebracht haben, so können wir das gut verstehen. Wenn Sie den Operator local sehen, sollten Sie einfach »sichern« denken, das könnte helfen. Falls Sie neuen Code schreiben, verwenden Sie einfach mit my deklarierte Variablen (lexikalische Variablen). Dadurch orientiert sich ihr Verhalten eher an traditionellen Variablen in anderen modernen Programmiersprachen. Zudem sind mit my deklarierte Variablen schneller als die sogenannten »lokalen«, bei denen es sich eigentlich um globale Variablen handelt. Seien Sie aber vorsichtig, wenn Sie den Code anderer Leute pflegen müssen. Sie können nicht einfach jedes local durch ein my austauschen, ohne zu überprüfen, ob der Programmierer vor Ihnen die Sichern-und-Wiederherstellen-Funktionalität benutzt hat.

Parameterlisten mit variabler Länge

In der rauhen Wirklichkeit werden oft Parameterlisten an Subroutinen übergeben, die eine beliebige Länge haben können. Dies liegt ebenfalls an der Perl eigenen Philosophie der »Grenzenlosigkeit«. Dies unterscheidet Perl von vielen traditionellen Programmiersprachen, bei denen für jede Subroutine ein striktes Typing gilt. Das bedeutet, daß immer nur eine vordefinierte Anzahl von Parametern, die einem vordefinierten Typ entsprechen müssen, erlaubt sind. Es ist zwar schön, daß Perl so flexibel ist; dies kann aber (wie wir bei der &max-Subroutine gesehen haben) zu Problemen führen, sobald wir die Subroutine mit einer anderen Anzahl von Argumenten aufrufen, als dies der Autor erwartet hat.

Es ist jedoch leicht zu überprüfen, ob die korrekte Anzahl von Argumenten übergeben wurde, indem wir das Array @_ auf seine Länge überprüfen. Um die Parameterliste von &max zu testen, hätten wir die Subroutine z.B. auch wie folgt schreiben können:17

 sub max {
   if (@_ != 2) {
     print "WARNUNG! Sie muessen &max genau zwei Argumente uebergeben!\n";
   }
 
   # weitermachen wie zuvor...
   .
   .
   .
 }

Die if-Überprüfung benutzt hier den Namen des Arrays in skalarem Kontext, um herauszufinden, wie viele Elemente es enthält. Dieses Verfahren kennen wir bereits aus Kapitel 3.

Auch diese Art der Überprüfung wird in der Praxis eher selten benutzt; es ist besser, die Subroutine so schreiben, daß sie sich auf die Parameter einstellt.

Eine bessere &max-Subroutine

Lassen Sie uns &max also so umschreiben, daß sie mit einer beliebigen Anzahl von Argumenten umgehen kann:

 $maximum = &max(3, 5, 10, 4, 6);
 
 sub max {
   my($max_bis_jetzt) = shift @_;  # Das erste Argument ist bis jetzt
                                   # das größte.
   foreach (@_) {                  # Die weiteren Argumente ansehen.
     if ($_ > $max_bis_jetzt) {    # Könnte dieser Wert vielleicht
       $max_bis_jetzt = $_;        # noch größer sein?
     }
   }
   $max_bis_jetzt;
 }

Dieser Code benutzt einen sogenannten »Hochwassermarken«-Algorithmus. Wenn nach einer Flut der Wasserstand sinkt, zeigt die Hochwassermarke, an welcher Stelle das Wasser seinen höchsten Stand hatte. In unserer Subroutine benutzen wir zum Festellen des bisher höchsten Pegelstandes die Variable $max_bis_jetzt, in der jeweils die größte bisher gefundene Zahl gespeichert wird.

Die erste Zeile setzt $max_bis_jetzt auf den Wert 3 (den ersten Parameter in unserem Beispiel). Dieser wird per shift aus dem Parameter-Array @_ entfernt und $max_bis_jetzt zugewiesen. Die Parameterliste enthält jetzt also nur noch die Werte (5, 10, 4, 6). Bis jetzt ist also der erste Parameter (3) die größte Zahl, da 3 die einzige Zahl ist, die wir bis jetzt gesehen haben.

Jetzt geht die foreach-Schleife die übrigen Werte aus der Parameterliste in @_ der Reihe nach durch. Standardmäßig wird als Schleifen-Kontrollvariable $_ benutzt. (Denken Sie aber daran: @_ und $_ haben prinzipiell nichts miteinander zu tun; sie haben nur zufällig ähnliche Namen.) Beim ersten Schleifendurchlauf erhält $_ den Wert 5. Die if-Überprüfung stellt fest, daß 5 größer ist als der Wert, der bisher in $max_bis_jetzt gespeichert war, also wird $max_bis_jetzt auf den Wert 5 gesetzt - die neue Hochwassermarke.

Beim nächsten Schleifendurchlauf hat $_ den Wert 10. Das ist ein Rekordhochwasser, also wird nun dieser Wert in $max_bis_jetzt gespeichert.

Einen Durchlauf später hat $_ den Wert 4. Der if-Test schlägt fehl, da 4 kleiner ist als der in $max_bis_jetzt gespeicherte Wert. Daraufhin wird der Körper der if-Überprüfung übersprungen.

Noch einen Schleifendurchlauf weiter hat $_ den Wert 6, also wird auch dieses Mal die von der if-Überprüfung abhängige Neuzuweisung übersprungen. Da sich keine weiteren Werte mehr in der Parameterliste befinden, wird an dieser Stelle die Schleife beendet.

Schließlich wird $max_bis_jetzt als Rückgabewert verwendet. Dies ist die größte Zahl, die wir bei unserer Überprüfung gefunden haben: 10.

Leere Parameterlisten

Der verbesserte &max-Algorithmus funktioniert jetzt schon wesentlich besser, selbst wenn mehr als zwei Parameter übergeben werden. Aber was passiert, wenn überhaupt kein Wert übergeben wird?

Auf den ersten Blick scheint dieser Fall etwas zu esoterisch zu sein, um sich darüber Sorgen zu machen. Warum sollte jemand &max aufrufen, ohne irgendwelche Parameter zu übergeben? Das kommt selten vor, aber vielleicht haben Sie ja eine Zeile wie diese in Ihrem Programm:

 $maximum = &max(@zahlen);

Das Array @zahlen kann unter Umständen eine leere Liste enthalten, vielleicht wurde sie auch aus einer Datei gelesen, die sich als leer herausgestellt hat. Was tut &max also in einem solchen Fall?

In der ersten Zeile der Subroutine wird versucht, der Variablen $max_bis_jetzt den mit shift aus dem (jetzt leeren) Array @_ entfernten ersten Wert zuzuweisen. Das ist völlig harmlos. Das Array bleibt leer, und shift weist $max_bis_jetzt den Wert undef zu.

Als nächstes soll mit der foreach-Schleife über @_ iteriert werden. Da das Array jedoch leer ist, wird die Schleife nicht ausgeführt.

Der Rückgabewert unserer Subroutine (der Wert von $max_bis_jetzt) ist also ebenfalls undef. Wenn die Liste keine definierten Werte enthält, ist undef also die einzig richtige Antwort.

Selbstverständlich sollte derjenige, der die Subroutine aufruft, sich darüber im klaren sein, daß der Rückgabewert undef sein kann - oder man könnte einfach sicherstellen, daß die Parameterliste niemals leer ist.

Anmerkungen zu lexikalischen (my-) Variablen

Lexikalische Variablen können übrigens in jedem beliebigen Block benutzt werden, nicht nur innerhalb einer Subroutine; zum Beispiel in Blöcken einer Fallunterscheidung mit if oder einer Schleife mit while oder foreach:

 foreach (1..10) {
   my($quadrat) = $_ * $_;	# für diese Schleife private Variable 	
                                # $quadrat
   print "$_ zum Quadrat ist $quadrat.\n";
 }

Die Variable $quadrat ist innerhalb des umschließenden Blocks als private (lexikalische) Variable angelegt. In diesem Fall ist dies der Block der foreach-Schleife. Gibt es keinen umschließenden Block, so ist die Variable innerhalb der gesamten Quellcode-Datei als private Variable angelegt. Momentan benutzen Ihre Programme zwar nur eine Datei für den Quellcode, das kann sich aber ändern. Das wichtige Konzept dahinter ist, daß der Geltungsbereich eines lexikalischen Variablennamens auf den kleinsten umschließenden Block bzw. die Datei beschränkt ist. Der einzige Code, der $quadrat benutzen kann, befindet sich im gleichen Geltungsbereich wie die Variable. Dadurch wird die Pflege Ihres Codes erheblich leichter: Wird in $quadrat ein falscher Wert gefunden, so kann der Schuldige in einem begrenzten Codestück aufgespürt werden. Erfahrene Programmierer haben (oft auf die harte Tour) gelernt, daß die Begrenzung des Geltungsbereichs einer Variable auf eine Seite Code (oder noch besser: auf ein paar Zeilen) den Entwicklungs- und Testzyklus erheblich beschleunigen kann.

Beachten Sie auch, daß der my-Operator den Kontext einer Zuweisung nicht verändert:

 my($num) = @_;  # Listenkontext, das gleiche wie ($num) = @_;
 my $num  = @_;  # skalarer Kontext, das gleiche wie $num = @_;

Im ersten Beispiel erhält $num den ersten Parameter von @_ in Form einer Zuweisung im Listenkontext. Im zweiten Beispiel erhält er statt dessen die Anzahl der Elemente im skalaren Kontext. Hierbei könnte jede der beiden Codezeilen das sein, was der Programmierer wollte. Anhand nur einer Zeile läßt sich das jedoch nicht feststellen. Daher kann Perl Sie auch nicht warnen, wenn Sie die falsche Variante benutzen. (Selbstverständlich sollten Sie nicht beide Zeilen in der gleichen Subroutine verwenden, da Sie keine zwei lexikalischen Variablen gleichen Namens innerhalb des gleichen Geltungsbereiches deklarierenn können; dies ist nur ein Beispiel.) Der Kontext ändert sich bei der Benutzung von my also nicht.

Selbstverständlich lassen sich mit my auch neue private Arrays anlegen:18

 my @telefon_nummern;

Neu angelegte Variablen sind zu Beginn immer leer - das bedeutet undef für Skalare und eine leere Liste bei Arrays.

Das »use strict«-Pragma

Perl ist eine recht »freizügige« Sprache. Aber vielleicht wollen Sie Perl ja ein wenig mehr Disziplin auferlegen. Hierfür gibt es das use strict-Pragma.

Unter einem Pragma verstehen wir einen Hinweis an den Compiler, der etwas über den Code aussagt. In diesem Fall teilt das Pragma use strict dem internen Compiler von Perl mit, für den Rest des Blocks oder der Quellcode-Datei einige gute Programmierregeln anzuwenden.

Wozu könnte das gut sein? Stellen Sie sich einmal vor, Sie schreiben in Ihrem Programm eine Zeile wie diese:

 $bam_bam = 3;  # Perl erzeugt diese Variable automatisch

Danach schreiben Sie eine Zeitlang weiter. Nachdem die Zeile vom Bildschirm verschwunden ist, geben Sie nun die folgende Zeile ein, um die Variable zu erhöhen:

 $bambam += 1;  # Hoppla!

Da Perl hier einen neuen Variablennamen findet (der Unterstrich in einem Variablennamen ist wichtig), wird eine neue Variable erzeugt und diese erhöht. Wenn Sie schlau sind und Glück haben, haben Sie die Warnungen eingeschaltet und Perl kann Sie darüber informieren, daß eine oder beide globalen Variablennamen jeweils nur einmal in Ihrem Programm vorkommen. Wenn Sie allerdings nur schlau sind, so kommen beide Namen nicht nur einmal in Ihrem Programm vor und Perl kann Sie folglich auch nicht warnen.

Um Perl mitzuteilen, daß Sie ab jetzt etwas restriktiver vorgehen wollen, schreiben Sie das use strict-Pragma an den Beginn Ihres Programms (oder in einen beliebigen Block oder eine Datei, in der Sie diese Regeln anwenden wollen):

 use strict;  # Einige gute Programmierregeln anwenden

Jetzt wird Perl neben anderen Einschränkungen19 darauf bestehen, daß Sie Ihre Variablen mit my deklarieren:20

 my $bam_bam = 3;  # Neue lexikalische Variable

Jetzt kann Perl sich beschweren, wenn Sie versehentlich eine Variable mit dem Namen $bambam deklarieren, wodurch der Fehler schon zur Compile-Zeit abgefangen werden kann.

 $bambam += 1;	# Es gibt keine Variable mit diesem Namen: 
	        # Fehler zur Compile-Zeit

Diese Einschränkung gilt natürlich nur für neue Variablen; die in Perl eingebauten Variablen wie $_ und @_ müssen niemals extra deklariert werden.21

Wenn Sie das use strict-Pragma in ein bereits geschriebenes Programm einbauen, werden Sie in der Regel eine wahre Flut von Fehlermeldungen bekommen. Daher ist es besser, das Pragma zu benutzen, wenn es gebraucht wird: zu Beginn der Programmierarbeiten.

Die meisten Leute empfehlen bei allen Programmen, deren Quellcode nicht mehr auf einen Bildschirm passt, use strict zu benutzen. Ganz unsere Meinung.

Von jetzt an werden die meisten (aber nicht alle) unserer Beispiele so geschrieben sein, als wäre use strict benutzt worden, auch wenn wir die Anweisung nicht jedesmal ausdrücklich zeigen. Das heißt, wo es angemessen ist, deklarieren wir die Variablen in der Regel mit my. Aber selbst wenn wir das hier nicht immer tun, möchten wir Sie dazu ermuntern, use strict in möglichst jedem Ihrer Programme zu benutzen.

Der return-Operator

Der Operator return gibt sofort bei seinem Aufruf einen Wert aus einer Subroutine zurück.

 my @namen    = qw/ Fred Barney Betty Dino Wilma Pebbles Bam-Bam /;
 my $ergebnis = &welches_element_ist("Dino", @namen);
 
 sub welches_element_ist {
   my($was, @liste) = @_;
   foreach (0..$#liste) {  # Indizes der Elemente von @liste
     if ($was eq $liste[$_]) {
       return $_;         # Richtiges Element gefunden, Wert sofort
                          # zurückgeben
     }
   }
   -1;                    # Element nicht gefunden (return ist 
                          # hier optional)
 }

Die Subroutine wird benutzt, um im Array @namen den Index von »Dino« zu finden. Zuerst wird mit my eine Parameterliste deklariert: Es gibt das $was, nach dem wir suchen, und eine @liste von Werten, in der gesucht wird. Dies ist in unserem Fall eine Kopie des Arrays @namen. Die foreach-Schleife geht die Indizes der Werte von @liste der Reihe nach durch (wie in Kapitel 3 gezeigt, ist der erste Index 0 und der letzte $#liste).

Für jeden Schleifendurchlauf testen wir, ob $was dem Element aus unserer @liste, das den aktuellen Index trägt, gleicht22. Ist dies der Fall, wird der aktuelle Index sofort zurückgegeben. Dies ist in Perl die häufigste Verwendung des Schlüsselwortes return - einen Wert sofort zurückzugeben, ohne den Rest einer Subroutine auszuführen.

Und wenn wir nun überhaupt kein Element gefunden hätten? In diesem Fall hat sich der Autor der Subroutine entschieden, als Code für »kein Wert gefunden« -1 zurückzugeben. Vermutlich wäre es etwas »perliger«, in diesem Fall undef zurückzugeben. Da dies die letzte in der Subroutine ausgeführte Anweisung ist, wurde auf die Verwendung von return verzichtet, obwohl return -1 auch nicht falsch gewesen wäre.

Manche Programmierer bevorzugen es, jedesmal, wenn es einen Rückgabewert gibt, return zu benutzen, da sich auf diese Art der Code selbst dokumentiert. Dies könnte zum Beispiel sinnvoll sein, wenn der Rückgabewert nicht in der letzten Codezeile der Subroutine steht, wie es zum Beispiel bei &liste_von_fred_bis_barney weiter vorn in diesem Kapitel der Fall ist. Hier wird return nicht wirklich benötigt, tut aber auch niemandem weh. Manche Perl-Programmierer sehen hierin allerdings nur sieben Zeichen, die man zusätzlich eingeben muß. Sie sollten also in der Lage sein, beide Arten von Code zu verstehen.

Wird return ohne weiteren Ausdruck benutzt, so wird ein leerer Wert zurückgegeben, also undef in skalarem Kontext und eine leere Liste im Listenkontext. return ( ) funktioniert genauso, falls Sie einmal explizit sein wollen.

Das Ampersand-Zeichen weglassen

Wie versprochen, erklären wir Ihnen jetzt die Regel, nach der Sie bei einem Subroutinen-Aufruf das Ampersand-Zeichen (&, Kaufmanns-Und) weglassen können. Dies ist immer dann der Fall, wenn die Subroutine vor Ihrem Aufruf deklariert wird oder aus der Syntax klar erkennbar ist, daß es sich um einen Funktionsaufruf23 handelt. So erkennt Perl eine Subroutine beispielsweise an einer in runden Klammern stehenden Parameterliste, die dem Namen der Routine nachgestellt ist. Ist mindestens eine dieser Bedingungen erfüllt, kann das &-Zeichen weggelassen werden. Die Subroutine kann nun wie eine eingebaute Funktion aufgerufen werden. (In dieser Regel versteckt sich jedoch eine kleine Falle, wie wir gleich sehen werden.)

 my @karten = mischen(@kartenspiel); 
                        # &mischen kann ohne & aufgerufen werden

Wird die Subroutine in Ihrem Programm bereits vor Ihrem Aufruf definiert, können Sie sogar die runden Klammern um die Parameterliste weglassen:

 sub division {
   $_[0] / $_[1];       # ersten Parameter durch zweiten dividieren
 }
 
 my $quotient = division 355, 113;  # &division benutzen

Dies funktioniert, da runde Klammern weggelassen werden dürfen, solange dies die Bedeutung des Codes nicht verändert.

Falls Sie die Deklaration der Subroutine jedoch hinter ihren Aufruf stellen, hat der Compiler keine Ahung, was es mit dem versuchten Aufruf von division auf sich hat. Der Compiler muß die Definition vor dem Aufruf zu sehen bekommen, um einen Subroutinen-Aufruf wie eine eingebaute Funktion behandeln zu können.

Die Falle lauert jedoch woanders. Sie besteht nämlich darin, daß eine Subroutine den gleichen Namen wie eine eingebaute Funktion haben kann. Um Perl vor Verwechslungen zu bewahren, muß die Subroutine in einem solchen Fall mit einem Ampersand-Zeichen aufgerufen werden. Hierdurch stellen Sie sicher, daß tatsächlich die Subroutine aufgerufen wird und keine interne Funktion. Ohne Kaufmanns-Und können Sie die Subroutine nur dann aufrufen, wenn es keine eingebaute Funktion gibt, die den gleichen Namen trägt:

 sub chomp {
   print "Mampf, mampf!";
 }
 
 &chomp;  # Hier MUSS ein &-Zeichen benutzt werden!

Ohne das Kaufmanns-Und hätten wir das eingebaute chomp aufgerufen, obwohl wir die Subroutine &chomp definiert haben. Die eigentliche Regel, nach der Sie vorgehen sollten, lautet also: Solange Sie nicht die Namen aller in Perl eingebauten Funktionen kennen, sollten Sie das &-Zeichen beim Aufruf Ihrer eigenen Funktionen immer benutzen (also ungefähr bei Ihren ersten hundert Programmen). Wenn Sie sehen, daß andere Leute das Ampersand-Zeichen in ihrem Code weggelassen haben, so muß das kein Fehler sein, sondern bedeutet nur, daß es offensichtlich in Perl keine eingebaute Funktion mit gleichem Namen gibt.24

Oft benutzen Programmierer Prototypen, wenn sie planen, ihre Subroutinen auf die gleiche Art wie Perls eingebaute Funktionen aufzurufen. Dies geschieht oft beim Schreiben von Modulen. Prototypen sagen Perl, welche Parameter zu erwarten sind. Das Schreiben von Modulen ist ein Thema für Fortgeschrittene; Sie können sich aber, wenn Sie soweit sind, die Perl-Dokumentation (insbesondere die Dokumente perlmod und perlsub) zu den Themen Subroutinen, Prototypen und Modulen ansehen.

Übungen

Die Antworten zu diesen Übungen finden Sie in Anhang A:

  1. [12] Schreiben Sie eine Subroutine mit dem Namen &gesamt, welche die Summe einer Liste von Zahlen zurückgibt. Hinweis: Die Subroutine sollte hierbei keine I/O-Operationen durchführen, sondern einfach ihre Parameter abarbeiten und das Ergebnis an den Aufrufer zurückgeben. Probieren Sie es mit diesem Beispielprogramm, das einfach nur die Subroutine aufruft, um die Funktionsweise zu testen. Die erste Gruppe von Zahlen sollte zusammen 25 ergeben.
 my @fred        = qw{ 1 3 5 7 9 };
 my $fred_gesamt = &gesamt(@fred);
 print "Die Summe von \@fred ist $fred_gesamt.\n";
 print "Geben Sie einige Zahlen jeweils auf einer eigenen Zeile ein:   
\n"; my $benutzer_gesamt = &gesamt(<STDIN>); print "Der Summe der von Ihnen eingegebenen Zahlen ist
$benutzer_gesamt.\n";
    Zur Lösung
  1. [5] Benutzen Sie die Subroutine aus der vorigen Übung, um ein Programm zu schreiben, das die Summe der Zahlen von 1 bis 1000 berechnet..
    Zur Lösung

Fußnoten

1

Im Gegensatz zu Pascal unterscheiden wir in Perl nicht zwischen einer Funktion, die einen Wert zurückgibt, und einer Prozedur, die dies nicht tut. Eine Subroutine in Perl ist immer benutzerdefiniert, während eine Funktion dies nicht umbedingt sein muß. Das bedeutet: Das Wort Funktion kann als Synonym für Subroutine benutzt werden, oder es kann eine von den Funktionen meinen, die in Perl eingebaut sind. Deshalb heißt dieses Kapitel auch Subroutinen, da es um die Funktionen geht, die Sie selbst definieren können und nicht um die eingebauten. Meistens jedenfalls.

2

Die Codebeispiele in diesem Buch stammen zu 40% aus der Post-Konsumenten-Programmierung und sind zu mindestens 75% in Ihren Programmen recyclingfähig, wenn sie korrekt getrennt werden.

3

Liebe Puristen, wir geben ja zu, daß die geschweiften Klammern eigentlich Teil des Codeblocks sind, wenn man es genaunimmt. Auch verlangt Perl nicht, Code einzurücken - der Wartungsprogrammierer aber schon. Halten Sie sich also lieber an die Stilvorgaben.

4

Es sei denn, Ihre Subroutine ist besonders trickreich angelegt und deklariert einen »Prototyp«, der den Compiler anweist, die aufrufenden Argumente auf eine bestimmte Art und Weise zu parsen und zu interpretieren. In dem seltenen Fall, daß Sie so etwas brauchen, finden Sie die nötigen Informationen in der perlsub-Manpage.

5

Wenn Sie richtig schlau sein wollen, lesen Sie, was in der Dokumentation über Codereferenzen steht, die in privaten (lexikalischen) Variablen gespeichert werden.

6

Ein Vergehen, vor dem Perl Sie warnt, wenn Sie wollen.

7

Und regelmäßig auch ein nachgestelltes Paar runder Klammern, selbst wenn diese leer sind. So wie wir sie hier geschrieben haben, würde unsere Subroutine den Wert von @_ von einer aufrufenden Subroutine »erben«. Wir werden gleich darauf kommen; hören Sie also hier nicht auf zu lesen, denn Sie könnten sonst Code schreiben, der Dinge tut, die Sie nicht erwarten!

8

Der Rückgabewert von print ist wahr bei einer erfolgreichen Operation und falsch, wenn die Ausgabe fehlschlägt. Wie festgestellt wird, ob eine Operation fehlgeschlagen ist, steht in Kapitel 11, Dateihandles und Dateitests.

9

Mit Hilfe der Funktion wantarray können Sie feststellen, ob eine Subroutine in skalarem Kontext oder im Listenkontext ausgewertet wird. Dies ermöglicht Ihnen, ohne viel Aufwand Subroutinen zu schreiben, die je nach Kontext skalare Werte oder Listenwerte zurückgeben.

10

Sofern vor dem Namen der aufgerufenen Subroutine ein Kaufmanns-Und-Zeichen steht und diese ohne nachgestellte runde Klammern (oder Argumente) benutzt wird, »erbt« die aufgerufene Subroutine das Array @_ von der aufrufenden Routine. Das ist in der Regel keine gute Idee, kann aber manchmal ganz nützlich sein.

11

Sie erkennen hier vielleicht den gleichen Mechanismus, der auch bei der foreach-Schleife zur Anwendung kommt. In beiden Fällen sichert Perl den Wert einer Variablen und stellt ihn automatisch wieder her.

12

Fortgeschrittene Programmierer werden erkennen, daß die lexikalische Variable auch außerhalb des Geltungsbereiches zugänglich sein kann. Dies läßt sich mit Hilfe von Referenzen bewerkstelligen, aber niemals mit dem Variablennamen selbst.

13

Wenn das Programm natürlich bereits eine Subroutine mit dem Namen &max hätte, würden wir das durcheinanderbringen.

14

Wir hätten Larry ja dazu geraten, Yahoo!-Aktien zu kaufen, aber Chip ist einfach idealistischer als wir.

15

Beziehungsweise ihn zu beschädigen, verschieben, lesen, testen, anzurühren, anzusehen, zu verändern oder auszugeben. Es gibt innerhalb von Perl keine Möglichkeit, an den gesicherten Wert heranzukommen.

16

Oder, um ganz genau zu sein, wenn die Ausführung des kleinsten umschließenden Blocks oder der Datei beendet ist.

17

Sobald Sie (in Kapitel 11) die Funktion warn kennengelernt haben, werden Sie wissen, wie Sie eine inkorrekte Benutzung Ihrer Subroutine in eine korrekte Warnung verwandeln können. Oder Sie entscheiden, daß dieser Fall wichtig genug ist, um die Funktion die zu benutzen, die im gleichen Kapitel vorgestellt wird.

18

Oder auch Hashes, wie wir im nächsten Kapitel sehen werden.

19

Wenn Sie mehr über die Beschränkungen wissen wollen, lesen Sie die Dokumentation für strict. Die Dokumentation für ein Pragma finden Sie unter dem Namen des Pragmas; die Eingabe von perldoc strict (oder der auf Ihrem System funktionierenden Dokumentationsmethode) sollte die nötigen Dokumente für Sie finden. Kurz gesagt: Die Einschränkungen sorgen dafür, daß Strings in den meisten Fällen in Anführungszeichen stehen müssen und daß Referenzen echte (harte) Referenzen sein müssen. Für Perl-Anfänger bedeuten diese Einschränkungen jedoch kaum eine Änderung.

20

Es gibt nämlich auch noch andere Möglichkeiten, eine Variable zu deklarieren.

21

Und zumindest unter gewissen Umständen müssen auch $a und $b nicht gesondert deklariert werden, da sie intern von sort benutzt werden. Wenn Sie dieses Feature testen, sollten Sie also andere Variablennamen benutzen als diese zwei. Übrigens ist die Tatsache, daß use strict diese zwei Namen nicht verbietet, der am häufigsten gemeldete Fehler in Perl, der gar keiner ist.

22

Es ist Ihnen doch aufgefallen, daß wir hier eq (equal, engl. gleich), den Vergleichsoperator für Strings, anstelle des numerischen Gegenstücks == benutzt haben, oder?

23

In diesem Fall ist die Funktion die Subroutine &mischen. Wie wir gleich erläutern werden, könnte es sich hierbei auch um eine eingebaute Funktion handeln.

24

Oder es handelt sich doch um einen Fehler. Um herauszufinden, ob es sich um eine eingebaute Funktion handelt, können Sie die Manpages perlfunc und perlop durchsuchen. Außerdem wird Perl Sie bei eingeschalteten Warnungen darauf hinweisen.


TOC PREV Übungen NEXT INDEX

Copyright © 2002 by O'Reilly Verlag GmbH & Co.KG