SELFHTML: Perl / Funktionsreferenz / Funktionen für die Kontrolle des laufenden Scripts
Author: Redaktion SELFHTML, selfhtml81@selfhtml.org
Description: Welche Funktionen es in Perl gibt, um Scripts kontrolliert ablaufen zu lassen.
Keywords: SELFHTML, Perl, Funktionen, Perl-Funktionen, Script-Ablauf, Kontrolle, Fehlerbehandlung, Error-Handling, caller, defined, die, eval, exit, local, my, quotemeta, reset, return, scalar, wantarray, warn
Date: 2005-11-09T00:29:27+01:00

| # Funktionen für die Kontrolle des laufenden Scripts
| Allgemeines zu diesen Funktionen caller - Aufrufkontext ermitteln defined - Definition einer Variablen überprüfen die - Script wegen eines Fehlers abbrechen eval - Anweisungen oder Anweisungsblöcke interpretieren lassen exit - Script beenden local - Wert von Variablen lokal begrenzen my - Gültigkeitsbereich von Variablen begrenzen quotemeta - Alle Zeichen außer A-Z, a-z, 0-9 und _ maskieren return - aus Subroutine zurückkehren und Wert zurückgeben scalar - Ausdruck in skalarem Kontext bewerten wantarray - Überprüfen ob Listenkontext gegeben ist warn - Warnungen ausgeben

## Allgemeines zu diesen Funktionen

Die hier versammelten Funktionen dienen vor allem dazu, bestimmte Dinge für das Script festzulegen, zu kontrollieren oder den Ablauf des Scripts zu beeinflussen. So kann eine Subroutine beispielsweise ermitteln, von wo aus sie aufgerufen wurde. Für eine Variable kann überprüft werden, ob sie einen Wert besitzt oder nicht. Die Gültigkeit (Lebensdauer) von Variablen kann auf bestimmte Bereiche des Scripts begrenzt werden. Scripts können in Fehlerfällen oder kritischen Situationen abgebrochen werden oder Warnungen ausgeben.

## caller - Aufrufkontext ermitteln

Ermittelt, von wo aus der aktuelle Programmteil aufgerufen wurde, und aus welchem Kontext heraus.

Erwartet als Parameter:
1. (optional) die Rückverfolgungstiefe als Zahl. Wenn Sie mit diesem Parameter experimentieren wollen, probieren Sie zunächst, den Wert `1` zu übergeben. Höhere Werte können dazu führen, dass weniger Information ermittelt wird als erhofft.

Gibt wahlweise einen Skalar oder eine Liste zurück. Wenn der Rückgabewert nur in einem Skalar gespeichert wird, enthält dieser nach Aufruf der Funktion den Namen des aufrufenden Packages. Welche weiteren Rückgabewerte in einer Liste gespeichert werden, zeigt das folgende Beispiel.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    my $Infos = Aufrufe_Starten();
    print "$Infos\n";
    print "</body></html>\n";

    sub Aufrufe_Starten {
      my $Info_Einfach = Aufruf_Info_Einfach();
      my $A_S = "<h3>Einfache Aufruf-Infos:</h3><p>".$Info_Einfach."</p>";
      my $Info_Ausfuehrlich = Aufruf_Info_Ausfuehrlich();
      $A_S = $A_S."<h3>Ausführliche Aufruf-Infos:</h3><p>".$Info_Ausfuehrlich."</p>";
      return($A_S);
    }

    sub Aufruf_Info_Einfach {
       (my $Package, my $Datei, my $Zeile) = caller();
       my $A_I_E = "<strong>Aufruf erfolgte aus Package:</strong> ".$Package."<br>" if (defined $Package);
       $A_I_E = $A_I_E."<strong>Aufruf erfolgte aus Datei:</strong> ".$Datei."<br>" if (defined $Datei);
       $A_I_E = $A_I_E."<strong>Aufruf erfolgte aus Programmzeile:</strong> ".$Zeile if (defined $Zeile);
       return($A_I_E);
    }

    sub Aufruf_Info_Ausfuehrlich {
       (my $Package, my $Datei, my $Zeile, my $Subroutine, my $HasArgs, my $WantArray, my $EvalText, my $IsRequire) = caller(1);
       my $A_I_A = "<strong>Aufruf erfolgte aus Package:</strong> ".$Package."<br>" if (defined $Package);
       $A_I_A = $A_I_A."<strong>Aufruf erfolgte aus Datei:</strong> ".$Datei."<br>" if (defined $Datei);
       $A_I_A = $A_I_A."<strong>Aufruf erfolgte aus Programmzeile:</strong> ".$Zeile."<br>" if (defined $Zeile);
       $A_I_A = $A_I_A."<strong>Aufruf erfolgte aus Subroutine:</strong> ".$Subroutine."<br>" if (defined $Subroutine);
       $A_I_A = $A_I_A."<strong>HasArgs:</strong> ".$HasArgs."<br>" if (defined $HasArgs);
       $A_I_A = $A_I_A."<strong>WantArray:</strong> ".$WantArray."<br>" if (defined $WantArray);
       $A_I_A = $A_I_A."<strong>EvalText:</strong> ".$EvalText."<br>" if (defined $EvalText);
       $A_I_A = $A_I_A."<strong>IsRequire:</strong> ".$IsRequire."<br>" if (defined $IsRequire);
       return($A_I_A);
    }

### Erläuterung:

Das Beispiel gibt HTML-Code aus. Während der HTML-Ausgabe wird die Subroutine `Aufrufe_Starten()` aufgerufen. Der Rückgabewert des Aufrufs wird in dem Skalar `$Infos` gespeichert und anschließend ausgegeben.
Die Subroutine `Aufrufe_Starten()` ruft ihrerseits wieder die Subroutinen `Aufruf_Info_Einfach()` und `Aufruf_Info_Ausfuehrlich()` auf. Aus den Rückgabewerten dieser beiden Routinen wird eine Zeichenkette namens `$A_S` zusammengesetzt und zurückgegeben.
In `Aufruf_Info_Einfach` steht die einfache Variante eines typischen Aufrufs von `caller`. Dabei werden drei Listenelemente als Rückgabewert erwartet: der Name des aufrufenden Packages, der aufrufenden Perl-Datei, und die Nummer der Programmzeile, in der der Aufruf erfolgte.
Die Subroutine `Aufruf_Info_Ausfuehrlich` zeigt dagegen den erweiterten Aufruf von `caller`. Dabei werden acht Listenelemente als Rückgabewerte erwartet. Neben den drei Elementen der einfachen Variante sind das der Name der aufrufenden Subroutine und folgende Zusatzinformationen:
`$HasArgs` ist 1, wenn beim Aufruf Argumente übergeben wurden (dazu zählt auch eine leere Liste), ansonsten 0.
`$WantArray` speichert, ob die Funktion im Listenkontext aufgerufen wurde.
`$EvalText` speichert einen Inhalt, wenn der Aufruf aus einer eval()-Bewertung heraus erfolgt (jedoch nicht unbedingt bei Blockbewertungen mit `eval{...}`).
`$IsRequire` speichert `1` als Inhalt, wenn der Aufruf aus `eval` heraus erfolgte, und wenn dabei eine der Funktionen use oder require im Spiel sind.
Die beiden Subroutinen `Aufruf_Info_Einfach` und `Aufruf_Info_Ausfuehrlich` im obigen Beispiel stellen aus den gewonnenen Informationen die Zeichenketten `$A_I_E` bzw. `$A_I_A` zusammen und geben diese am Ende zurück.

## defined - Definition einer Variablen überprüfen

Variablen, egal, ob Skalare, Listen- bzw. Array-Elemente oder Hash-Elemente, haben, solange ihnen nicht explizit irgendein Wert zugewiesen wird, den Wert `undef`. Mit dieser Funktion können Sie überprüfen, ob einer Variablen bereits ein Wert zugewiesen wurde oder nicht.

Erwartet als Parameter:
1. die zu überprüfende Variable.

Gibt `1` bzw. ein logisches "wahr" zurück, wenn der Variablen ein Wert zugewiesen ist, und `0` bzw. ein logisches "falsch", wenn kein Wert zugewiesen ist.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my $ErsterSatz;
    my $ZweiterSatz = "Den ersten beissen die Katzen";

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    &Satz_aufsagen;
    $ErsterSatz = "...und den letzten wie bekannt die Hunde";
    undef $ZweiterSatz;
    print "<p></p><i>So - und jetzt noch einmal:</i></p>";
    &Satz_aufsagen;
    print "</body></html>\n";

    sub Satz_aufsagen {
      if(defined $ErsterSatz) {
        print "Der erste Satz lautet <strong>$ErsterSatz</strong><br>\n";
      }
      if(defined $ZweiterSatz) {
        print "Der zweite Satz lautet <strong>$ZweiterSatz</strong><br>\n";
      }
    }

### Erläuterung:

Das Beispielscript definiert zunächst zwei Skalare namens `$ErsterSatz` ohne Wertzuweisung und `$ZweiterSatz` mit Wertzuweisung. Das Script enthält eine Subroutine namens `Satz_aufsagen`. Darin wird mit `defined` für die beiden Skalare überprüft, ob ihnen ein Wert zugewiesen wurde. Wenn ja, wird dieser Wert ausgegeben.
Das Script erzeugt HTML-Code und ruft dabei zunächst einmal die Subroutine `Satz_aufsagen` auf. Anschließend erhält der bislang undefinierte Skalar `$ErsterSatz` einen Wert, und der Skalar `$ZweiterSatz` wird mit undef in jenen Zustand versetzt, in dem ihm kein Wert (bzw. der "Nichtwert" `undef`) zugewiesen ist. Danach wird `Satz_aufsagen` nochmals aufgerufen.
Beim ersten Aufruf von `Satz_aufsagen` wird nur "Den ersten beissen die Katzen" ausgegeben, beim zweiten Aufruf nur "...und den letzten wie bekannt die Hunde".

### Beachten Sie:

Der Anfangswert `undef` einer Variablen, den Sie mit der Funktion `undef` wieder herstellen können, ist etwas anderes als der so genannte Leerstring (`""`). Eine leere Zeichenkette ist durchaus ein zugewiesener Wert!

## die - Script wegen eines Fehlers abbrechen

Beendet ein Script, wenn es keinen Sinn hat, das Script weiter auszuführen. Wird z.B. gern verwendet, wenn eine wichtige Datei nicht geöffnet werden kann.
Schreibt Fehlermeldungen auf die Standardfehlerausgabe `STDERR` und beendet das Script mit dem aktuellen Wert der vordefinierten Variablen `$!`. Bei der CGI-Schnittstelle eines Webervers ist die Standardfehlerausgabe meistens eine Log-Datei, in der solche Fehlermeldungen gesammelt werden. Suchen Sie gegebenenfalls in der Dokumentation zu Ihrem Webserver nach, wo und wie der Server CGI-Fehlermeldungen protokolliert.

Erwartet als Parameter:
1. Eine Liste, die auf die Standardfehlerausgabe `STDERR` geschrieben werden soll. Sinnvollerweise enthält die Liste eine oder mehrere entsprechende Fehlermeldungen.

### Beispiel:

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    open(TEXT, "</daten/texte/nichtda.txt") || die "Fehler aufgetreten: $!";
    my @Zeilen = <TEXT>;
    close(TEXT);

### Erläuterung:

Das Beispiel versucht, mit open eine Datei zu öffnen, die aber nicht vorhanden ist. Dadurch wird der Oder-Zweig hinter dem logischen Operator `||` (steht für "oder") aktiv. Dort ist die Funktion `die` notiert. Sie schreibt auf die Standardfehlerausgabe, dass ein Fehler aufgetreten ist. Indem sie dabei auch die vordefinierte Variable `$!` mit in die Ausgabe schreibt, wird auch mitprotokolliert, welcher Fehler aufgetreten ist. In diesem Fall ist auch die Anweisung `use CGI::Carp qw(fatalsToBrowser)` sehr hilfreich, denn der Fehler wird dadurch zusätzlich auf die Standardausgabe geschrieben und kann so je nach Situation im Browser zur Anzeige gelangen.

## eval - Anweisungen oder Anweisungsblöcke interpretieren lassen

Perl-Scripts werden normalerweise intern zu Operationscode (sogenannten Opcodes) kompiliert, bevor sie ausgeführt werden. Das merken Sie als Programmierer beispielsweise daran, dass der Perl-Interpreter vor der Ausführung abbricht, sobald das Script Syntaxfehler enthält. Mit Hilfe der `eval`-Funktion können Sie jedoch den Perl-Interpreter während der Laufzeit eines Scripts aufrufen und innerhalb des Scripts beliebigen Perl-Code interpretieren lassen. Wenn Sie so wollen, kann ein Perl-Script auf diese Weise selber Perl-Scripts schreiben und deren Ausführung in die eigene Ausführung einbetten. In die Code-Erzeugung dürfen natürlich auch Variableninhalte einfließen, die das Script verwaltet.

Erwartet als Parameter:
1. entweder eine Zeichenkette, die Perl-Code enthält, oder einen Anweisungsblock in geschweiften Klammern, vergleichbar einem Anweisungsblock innerhalb einer Subroutine oder innerhalb einer `if`-Abfrage.
Der Unterschied zwischen beiden Möglichkeiten besteht darin, dass eine übergebene Zeichenkette tatsächlich erst zur Laufzeit kompiliert wird, während der Anweisungsblock in der internen Vorab-Kompilierung mit berücksichtigt wird. Dadurch werden beispielsweise schwere Fehler, die zum Scriptabbruch führen, in einem übergebenen Anweisungsblock bereits bei der Kompilierung erkannt, in einer übergebenen Zeichenkette jedoch erst während der Ausführung.

Gibt das Ergebnis der zuletzt ausgeführten Anweisung in der übergebenen Zeichenkette oder dem übergebenen Anweisungsblock zurück. Im Fehlerfall wird `undef` zurückgegeben, und die aufgetretene Fehlermeldung ist über die vordefinierte Variable `$@` abfragbar.

### Beispiel 1 eines vollständigen CGI-Scripts in Perl:

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my $Rechenergebnis = eval($ENV{'QUERY_STRING'});

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    print "Das Ergebnis der übergebenen Rechenoperation lautet <strong>$Rechenergebnis</strong><br>\n";
    print "</body></html>\n";

### Erläuterung:

Das Script erwartet beim Aufruf einen Übergabeparameter, der über URI hinter einem Fragezeichen notiert wird. Der Übergabeparameter besteht in einer Rechenoperation. Es kann sich auch um geklammerte, komplexe Rechenausdrücke handeln, z.B. `((6+7)*4)+(5/7)`. Nur Leerzeichen sind bei diesem einfachen Beispielscript nicht erlaubt, da sie bei der Übergabe in der URI-Zeile umformatiert werden.
Über die CGI-Umgebungsvariable `$ENV{'QUERY_STRING'}` kann das Script auf die übergebene Rechenoperation zugreifen. Es übergibt die Umgebungsvariable gleich an die Funktion `eval`. Die wiederum übergibt die übergebene Zeichenkette, also die Rechenoperation, zur Laufzeit an den Perl-Interpreter. Zurückgegeben wird der Wert dieser Anweisung, und das ist in dem Fall einfach das Rechenergebnis, so wie Perl es in einem Skalar speichern würde, wenn man ihm diese Rechenoperation zuweisen würde.
Zur Kontrolle gibt das Script HTML-Code mit dem Rechenergebnis aus.

### Beachten Sie:

Scripts wie im Beispiel oben können extrem gefährlich sein. Benutzen Sie so etwas niemals als öffentlich zugängliches CGI-Script! Denn der übergebene Code, den das Script vom Anwender erhält, wird gnadenlos ausgeführt. Wenn der Anwender jemand ist, der sich auskennt, kann er statt der geforderten Rechenoperation beispielsweise einen Aufruf von system übergeben, bei dem ein ganzer Verzeichnisbaum gelöscht oder die Festplatte formatiert wird.

### Beispiel 2 eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my $Zahl_1 = int(rand(50));
    my $Zahl_2 = int(rand(5));
    my $Ergebnis;
    eval { $Ergebnis = $Zahl_1 / $Zahl_2; };

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";

    if($@) {
      print "Folgender Fehler ist aufgetreten: $@\n";
    }
    else {
      print "$Zahl_1 geteilt durch $Zahl_2 ist $Ergebnis\n";
    }
    print "</body></html>\n";

### Erläuterung:

In diesem Beispiel wird die Funktion `eval` wie in der Praxis oft üblich zum Abfangen von Fehlern verwendet. Das Script ermittelt mit rand zwei Zufallszahlen `$Zahl_1` und `$Zahl_2`. Anschließend dividiert es Zahl 1 durch Zahl 2. Da bei den ermittelten Zufallszahlen jedoch auch der Wert 0 vorkommen kann, würde ein schwerer Fehler auftreten, wenn Zahl 2 diesen Wert hat. Denn eine Division durch 0 führt auf allen Computersystemen zu einem Fehler. Das Script bettet die Anweisung mit der Division aus diesem Grund in einen `eval`-Block ein. Falls die Zahl 2 tatsächlich den Wert 0 hat, wird abgebrochen, und in der vordefinierten Variablen `$@` steht anschließend die von Perl erzeugte Fehlermeldung.
Das Beispiel gibt HTML-Code aus. Dabei fragt es ab, ob `$@` einen Inhalt enthält. Wenn ja, wird der Fehler ausgegeben. Wenn nein, wird das Ergebnis der erfolgreichen Division ausgegeben.

## exit - Script beenden

Beendet das Script und gibt einen Wert an den aufrufenden Prozess zurück.

Erwartet als Parameter:
1. (optional) einen zurückzugebenden Wert. Die üblichen Werte, die auch von fremden aufrufenden Prozessen am ehesten erkannt werden, sind `0` für "erfolgreich beenden" und `1` für "Beenden mit Fehler". Wenn Sie keinen Parameter übergeben, wird automatisch `0` verwendet.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus - ohne Übergabeparameter
Anzeigebeispiel: So sieht's aus - mit dem String "Newbie" als Übergabeparameter
(Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    if($ENV{'QUERY_STRING'} eq "") {
       HTML_Output("Username beim Aufruf erwartet!");
       exit(1);
    }
    else {
       HTML_Output("Hallo $ENV{'QUERY_STRING'}, wie geht's?");
       exit(0);
    }

    sub HTML_Output {
      print "Content-type: text/html\n\n";
      print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
      print "<html><head><title>Test-Ausgabe</title></head><body>\n";
      print "$_[0]\n";
      print "</body></html>\n";
    }

### Erläuterung:

Das Script erwartet beim Aufruf einen Übergabeparameter, der hinter einem an den URI angehängten Fragezeichen notiert wird. Der Übergabeparameter besteht in einem User-Namen. Durch Auswerten der CGI-Umgebungsvariablen `$ENV{'QUERY_STRING'}` gelangt das Script an den übergebenen Namen. Wenn die Umgebungsvariable leer ist (`""`), wurde kein Name übergeben. In diesem Fall ruft das Script die Subroutine `HTML_Output` auf und lässt sie eine Fehlermeldung senden. Anschließend wird das Script mit `exit(1)` beendet. Im anderen Fall, wenn alles in Ordnung ist und ein Name übergeben wurde, ruft das Script ebenfalls `HTML_Output` auf, diesmal jedoch mit einer netten Begrüßung des Users. In diesem Fall beendet sich das Script anschließend mit `exit(0)`.

### Beachten Sie:

Es ist kein guter Programmierstil, `exit` in Subroutinen zu verwenden. Wenn das Script in solchen Programmteilen fehlerhafte Situationen erkennt, sollte es besser mit return einen Wert zurückgeben, der an einer zentralen Stelle im Script als Fehler erkannt wird und dort zu einem Aufruf von `exit` führt.

## local - Wert von Variablen lokal begrenzen

Beschränkt den Wert einer Variablen (egal ob Skalar, Liste oder Hash usw.) auf lokale Gültigkeit. Die Beschränkung kann sich auf einen Anweisungsblock oder einen der Bereiche beziehen, die aus diesem Anweisungsblock heraus aufgerufen werden. Wenn es eine gleichnamige Variable außerhalb des Blocks gibt, wird dieser innerhalb des Anweisungsblocks temporär ein neuer Wert zugewiesen. Anwenden können Sie diese Funktion bei der Ersteinführung, also der Deklaration einer Variablen.

Beachten Sie, dass `local` nicht wirklich eine lokale Variable erzeugt, sondern nur eine globale Variable mit einem lokal gültigen Wert. Verwenden Sie `local` daher nur in begründeten Ausnahmefällen! "Echte" lokal gültige Variablen werden durch my deklariert.

Erwartet als Parameter:
1. eine Variable, der temporär ein neuer Wert zugewiesen werden soll.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);
    use vars qw($Zahl_1 $Zahl_2);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    my $Ergebnis = Subroutine_1();
    print "$Ergebnis\n";
    print "</body></html>\n";

    sub Subroutine_1 {
       local $Zahl_1 = 10;
       $Zahl_1 = $Zahl_1 * 2;
       $Zahl_2 = Subroutine_2();
       return($Zahl_1 + $Zahl_2);
    }

    sub Subroutine_2 {
      return($Zahl_1 + 100);

    }

### Erläuterung:

Das Beispiel deklariert zu Beginn zwei Skalare `$Zahl_1` und `$Zahl_2`. Dies sind globale Variablen, die überall Gültigkeit haben und an jeder Stelle des Scripts verändert werden können. Das Beispiel enthält weiter unten jedoch auch noch eine Subroutine namens `Subroutine_1`. Innerhalb dieser Subroutine, die aus Sicht von Perl einen Anweisungsblock darstellt, wird mit `local $Zahl_1` einer dieser globalen Variablen für die Subroutine `Subroutine_1` ein anderer Wert zugewiesen, nämlich `10`. Würde das `local` fehlen, so würde einfach der globalen Variablen `$Zahl_1` ein neuer Wert zugewiesen.
`$Zahl_1` wird in der darauffolgenden Anweisung mit 2 multipliziert. Hinterher steht `20` als Wert in `$Zahl_1`, da die Multiplikation mit dem temporären Wert `10` vorgenommen wird.
Aus `Subroutine_1` heraus wird anschließend `Subroutine_2` aufgerufen. Dort wird wiederum die Variable `$Zahl_1` verwendet. Zu diesem Zeitpunkt ist im Script-Ablauf der globale Wert `5` der Variablen `$Zahl_1` noch immer durch den temporären Wert `20` ersetzt. Da er auch in Bereichen Gültigkeit hat, die von `Subroutine_1` aus aufgerufen werden, wird dieser Wert innerhalb von `Subroutine_2` weiter verwendet (hier liegt ein sichtbarer Unterschied zur Funktion my). Zum aktuellen Wert 20 wird 100 addiert. Der Wert, den `Subroutine_2` mit return zurückgibt, lautet also 120.
`Subroutine_1` gibt nach dem Aufruf von `Subroutine_2` ebenfalls das Ergebnis einer Addition an den aufrufenden Befehl zurück. Da `$Zahl_2` den Wert `120` hat, wird also der Wert `140` zurückgegeben.
Im Hauptprogramm erzeugt das Beispiel HTML-Code. Dabei wird `Subroutine_1` aufgerufen und deren Rückgabewert im Skalar `$Ergebnis` gespeichert. Zur Kontrolle wird das Ergebnis ausgegeben.

## my - Gültigkeitsbereich von Variablen begrenzen

Schränkt den Gültigkeitsbereich einer Variablen (egal ob Skalar, Liste oder Hash usw.) auf einen Namensraum oder einen Anweisungsblock ein. Wenn es eine gleichnamige Variable außerhalb des Blocks gibt, wird diese nicht berührt. Anwenden können Sie diese Funktion bei der Definition einer Variablen.

Erwartet als Parameter:
1. eine Variable, deren Gültigkeitsbereich eingeschränkt werden soll.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);
    use vars qw($Zahl_1);

    $Zahl_1 = 1;

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    my $Ergebnis = Subroutine_1();
    print "$Ergebnis\n";
    print "</body></html>\n";

    sub Subroutine_1 {
       my $Zahl_1 = 10;
       my $Zahl_2 = Subroutine_2();
       return($Zahl_1 + $Zahl_2);
    }

    sub Subroutine_2 {
     return($Zahl_1 + 100);
    }

### Erläuterung:

Das Beispiel deklariert zu Beginn einen Skalar `$Zahl_1`. Dies ist eine globale Variable, die überall Gültigkeit hat und an jeder Stelle des Scripts verändert werden kann. Die Deklaration erfolgt mit dem Standardmodul `vars`. Der Grund dafür ist, dass die Verwendung von `use strict` sonst keine Deklaration globaler Variablen erlaubt und einen Fehler erzeugen würde. Im Beispiel sehen Sie, wie das Modul `vars` eingesetzt wird. Mit `use` eingebunden, steht in der Klammer hinter `qw` der Name `$Zahl_1`, also der Name der Variablen, die global deklariert werden soll. In der Klammer hinter `qw` können Sie als Liste, durch Leerzeichen getrennt, auch mehrere globale Variablen angeben.

Das Beispielscript enthält weiter unten eine Subroutine namens `Subroutine_1`. Innerhalb dieser Subroutine, die aus Sicht von Perl einen Anweisungsblock darstellt, wird mit `my $Zahl_1` eine Variable deklariert, die den gleichen Namen hat wie die globale Variable. Durch Anwendung von `my` ist es jedoch eine eigene neue Variable, die mit `10` initialisiert wird. Würde das `my` fehlen, so würde einfach der globalen Variablen `$Zahl_1` ein neuer Wert zugewiesen.
Aus `Subroutine_1` heraus wird `Subroutine_2` aufgerufen. Dort wird wieder die Variable `$Zahl_1` verwendet. Zu diesem Zeitpunkt im Script-Ablauf existieren beide Variablen `$Zahl_1`. Da diejenige, die in `Subroutine_1` deklariert wurde, jedoch nur dort Gültigkeit hat, ist innerhalb von `Subroutine_2` wieder die globale Variable gemeint. Zu deren Wert `1` wird `100` addiert. Der Wert, den `Subroutine_2` mit return zurückgibt, lautet also `101`.
`Subroutine_1` gibt nach dem Aufruf von `Subroutine_2` ebenfalls das Ergebnis einer Addition an den aufrufenden Befehl zurück. In diesem Fall ist mit `$Zahl_1` wieder diejenige Variable gemeint, die innerhalb des gleichen Blocks, also innerhalb von `Subroutine_1` deklariert wurde, und die den Wert `10` hat. Da `$Zahl_2` den Wert `101` hat, wird also der Wert `111` zurückgegeben.
Im Hauptprogramm gibt das Beispiel HTML-Code aus. Dabei wird `Subroutine_1` aufgerufen und deren Rückgabewert im Skalar `$Ergebnis` gespeichert. Zur Kontrolle wird das Ergebnis ausgegeben.

## quotemeta - Alle Zeichen außer A-Z, a-z, 0-9 und _ maskieren

Wandelt eine Zeichenkette so um, dass alle Zeichen außer A bis Z, a bis z, 0 bis 9 und Unterstrich _ mit einem Backslash `\` maskiert werden.

Erwartet als Parameter:
1. eine Zeichenkette, die umgewandelt werden soll.

Gibt die umgewandelte Zeichenkette zurück.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";

    my $Normaltext = "+++Test+++";
    my $Normallaenge = length($Normaltext);
    my $Quotematatext = quotemeta($Normaltext);
    my $Quotematalaenge = length($Quotematatext);

    print "<strong>$Normaltext</strong> wurde umgewandelt in <strong>$Quotematatext</strong><br>\n";
    print "Textlänge zuvor: <strong>$Normallaenge</strong> Zeichen<br>\n";
    print "Textlänge jetzt: <strong>$Quotematalaenge</strong> Zeichen\n";

    print "</body></html>\n";

### Erläuterung:

Das Beispiel erzeugt HTML-Code. Dabei demonstriert es die Wirkungsweise von `quotemeta`. Ein Skalar namens `$Normalext` wird zunächst mit einem Wert belegt, der neben dem Wort "Test" diverse Pluszeichen enthält. Außerdem wird mit length die Länge der Zeichenkette ermittelt. Durch die anschließende Anwendung der Funktion `quotemeta` auf `$Normaltext` werden die Pluszeichen maskiert. Der Rückgabewert der Funktion wird in einem neuen Skalar namens `$Quotemetatext` gespeichert. Auch dessen Länge wird mit `length` ermittelt. Zur Kontrolle gibt das Script alle ermittelten Daten aus. Die maskierte Version hat 6 Zeichen mehr, da jedes Pluszeichen maskiert wurde.

## return - aus Subroutine zurückkehren und Wert zurückgeben

Gibt einen Wert an die Anweisung zurück, welche die Subroutine aufgerufen hat.

Erwartet als Parameter:
1. (optional) ein Wert, der zurückgegeben werden soll. Es kann sich um eine Zahl, eine Zeichenkette oder um eine beliebige Variable (auch um eine komplette Liste oder einen Hash) handeln. Wenn kein Parameter übergeben wird, wird einfach die Subroutine verlassen und je nach zuletzt ausgeführtem Kontext eine leere Liste oder ein Skalar mit dem Wert `undef` zurückgegeben.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    my $Ausgabe = fett("eine wichtige Angelegenheit");
    print "<p>$Ausgabe</p>\n";
    $Ausgabe = kursiv("eine noch wichtigere Angelegenheit");
    $Ausgabe = fett($Ausgabe);
    print "<p>$Ausgabe</p>\n";
    print "</body></html>\n";

    sub fett {
      my $fetterText = "<strong>$_[0]</strong>";
      return $fetterText;
    }

    sub kursiv {
      my $kursiverText = "<i>$_[0]</i>";
      return $kursiverText;
    }

### Erläuterung:

Das Beispiel enthält zwei Subroutinen namens `fett` und `kursiv`. In beiden Subroutinen wird ein übergebener Parameter erwartet, der in dem vordefinierten Array für Übergabeparameter (`@_`) an erster Stelle (`$_[0]`) steht. Dieser übergebene Parameter wird in die HTML-Tags für fett bzw. kursiv gesetzt. Die Skalare `$fetterText` bzw. `$kursiverText`, die dieses Konstrukt speichern, werden anschließend mit `return` zurückgegeben.
Das Script erzeugt HTML-Code. Während der Ausgabe ruft es die beiden Subroutinen auf. Der Rückgabewert wird jeweils in dem Skalar `$Ausgabe` gespeichert. Im zweiten Fall werden sogar beide Subroutinen hintereinander aufgerufen. Dadurch wird der übergebene Text erst kursiv, dann fett, also insgesamt fett kursiv. Zur Kontrolle werden die HTML-Konstrukte ausgegeben.

### Beachten Sie:

Subroutinen geben auch dann etwas zurück, wenn sie nicht mit `return` verlassen werden. Wenn Sie beispielsweise eine Subroutine so aufrufen:
`$Ausgabe = Test();`
und die Subroutine so aussieht:
`sub Test { $x = 1; }`
dann ist in `$Ausgabe` anschließend der Wert `1` gespeichert.

## scalar - Ausdruck in skalarem Kontext bewerten

Erwartet als Parameter:
1. einen beliebigen Ausdruck. Es kann sich um eine Variable, einen Funktionsaufruf, eine Berechnung, eine Zuweisung usw. handeln.

Gibt den Wert zurück, den der übergebene Ausdruck bei skalarem Kontext liefert.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";
    my $Singular = "ein Tisch";
    my @Plural = ("ein Tisch","noch ein Tisch");
    my $Ausgabe_1 = scalar($Singular);
    my $Ausgabe_2 = scalar(@Plural);
    my $Ausgabe_3 = scalar(time() > 900000000 ? 1 : 0);
    print "Ausgabe 1: $Ausgabe_1<br>\n";
    print "Ausgabe 2: $Ausgabe_2<br>\n";
    print "Ausgabe 3: $Ausgabe_3\n";
    print "</body></html>\n";

### Erläuterung:

Das Beispiel gibt HTML-Code aus. Dabei definiert es einen Skalar namens `$Singular` und eine Liste namens `@Plural`. Auf beide wird die Funktion `scalar` angewendet. Der skalare Rückgabewert wird in den Skalaren `$Ausgabe_1` und `$Ausgabe_2` gespeichert. Außerdem wird noch ein dritter Skalar `$Ausgabe_3` definiert, dem der skalare Kontext einer komplexeren Anweisung zurückgegeben wird. In der Anweisung wird ermittelt, ob der Rückgabewert der Funktion time größer als 900000000 ist. Wenn ja, wird 1 zurückgegeben, wenn nein, wird 0 zurückgegeben. Anschließend gibt das Script die 3 ermittelten Werte aus.
`$Ausgabe_1` gibt einfach den Inhalt des Skalars `$Singular` aus, also `ein Tisch`. Da der bewertete Ausdruck ein Skalar ist, hat der skalare Kontext keinen Einfluss auf den zurückgegebenen Wert.
`$Ausgabe_2` gibt eine Zahl aus, nämlich 2. Der Grund ist, dass die skalare Interpretation einer Liste, im Beispiel der Liste `@Plural`, die Anzahl der Elemente ermittelt, die in der Liste enthalten sind.
`$Ausgabe_3` gibt 1 oder 0 aus, je nachdem, welchen Wert `time` zurückgeliefert hat. Da 1 und 0 normale Einzelwerte sind, ist der skalare Kontext bereits gegeben.

## wantarray - Überprüfen ob Listenkontext gegeben ist

Erwartet keine Parameter

Gibt `1` bzw. `TRUE` zurück, wenn das aufrufende Programm oder die aufrufende Subroutine einen Listenkontext erwartet, und `0` bzw. `FALSE`, wenn ein skalarer Kontext erwartet wird. Gibt `undef` zurück, wenn gar kein Kontext erwartet wird (sogenannter void context).

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";

    my @Zahlen = (1,2,3,4,5);

    my $Normalsumme = Summe_ermitteln(@Zahlen);
    print "Die normale Summe von 1,2,3,4,5 ist <strong>$Normalsumme</strong><br>\n";

    my @Kumulativsummen = Summe_ermitteln(@Zahlen);
    print "Die Kumulativsummen von 1,2,3,4,5 sind <strong>@Kumulativsummen</strong><br>\n";

    print "</body></html>\n";

    sub Summe_ermitteln {
       if(wantarray) {
         my @Summe = @_;
         my $Wert;
         foreach my $Summe (@Summe) {
            $Summe = $Wert += $Summe;
         }
         return @Summe;
       }
       else {
         my $Wert;
         foreach my $Summe (@_) {
            $Wert += $Summe;
         }
         return $Wert;
       }
    }

### Erläuterung:

Das Beispiel enthält eine Subroutine namens `Summe_ermitteln`. Die Funktion erwartet einen Array von Zahlen als Parameter, die über die Parameterliste `@_` abgefragt werden können. Innerhalb der Funktion wird mit `if(wantarray)` abgefragt, ob die Anweisung, die die Subroutine aufruft, als Rückgabewert eine Liste oder einen Skalar erwartet. Wenn eine Liste erwartet wird, wird der `if`-Zweig ausgeführt. Wenn ein Skalar erwartet wird, dann der `else`-Zweig. Im `if`-Zweig ist ein Algorithmus notiert, der aus den übergebenen Zahlen Kumulativsummen ermittelt. Die Kumulativsummen werden in einer Liste namens `@Summe` festgehalten. Diese Liste wird am Ende zurückgegeben. Im `else`-Zweig dagegen ermittelt die Funktion einfach nur die Summe der übergebenen Zahlen und hält das Ergebnis in dem Skalar `$Wert` fest, den sie am Ende zurückgibt.
Im Hauptprogramm wird HTML-Code erzeugt. Dabei wird insgesamt zweimal die Subroutine `Summe_ermitteln` aufgerufen. Einmal wird der Rückgabewert in einem Skalar namens `$Normalsumme` gespeichert, und beim anderen mal in einer Liste namens `@Kumulativsummen`. Dadurch wird beim ersten Aufruf der Subroutine der `else`-Zweig ausgeführt, und beim zweiten Aufruf der `if`-Zweig. Zur Kontrolle gibt das Script die jeweils ermittelten Ergebnisse aus.

## warn - Warnungen ausgeben

Schreibt Warnungen auf die Standardfehlerausgabe `STDERR`, ohne das Script zu beenden (im Gegensatz zu die). Für die CGI-Schnittstelle eines Webservers ist die Standardfehlerausgabe meistens eine Log-Datei, in der solche Fehlermeldungen gesammelt werden. Suchen Sie gegebenenfalls in der Dokumentation zu Ihrem Webserver nach, wo und wie der Server CGI-Fehlermeldungen protokolliert.

Erwartet als Parameter:
1. Eine Liste mit der oder den Meldungen, die auf die Standardfehlerausgabe `STDERR` geschrieben werden sollen.

### Beispiel eines vollständigen CGI-Scripts in Perl:

Anzeigebeispiel: So sieht's aus - ohne Übergabeparameter
Anzeigebeispiel: So sieht's aus - mit dem String "hallo" als Übergabeparameter
(Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my $Daten = $ENV{'QUERY_STRING'};

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Test-Ausgabe</title></head><body>\n";

    if(! -e "/tmp/idx.txt") {
      warn("idx.txt nicht gefunden. Datei wird deshalb neu erzeugt\n");
      open(FILE,">/tmp/idx.txt");
      print FILE "$Daten\n";
    }
    else {
      open(FILE,">>/tmp/idx.txt");
      print FILE "$Daten\n";
    }
    print "<strong>in Datei geschrieben:</strong> $Daten\n";
    close(FILE);

    print "</body></html>\n";

### Erläuterung:

Das Script erwartet einen Übergabeparameter, der hinter einem Fragezeichen notiert wird. Der Übergabeparameter ist in diesem Beispiel ein User-Name. Durch Auswerten der CGI-Umgebungsvariablen `$ENV{'QUERY_STRING'}` gelangt das Script an die übergebenen Daten.
Das Script erzeugt HTML-Code. Währenddessen versucht es, mit open eine Datei namens `/usr/web/temp/idx.txt` zu öffnen, um die übergebenen Daten ans Ende der Datei zu schreiben. Falls die Datei nicht existiert, wird sie im `if`-Zweig zwar neu erzeugt (falls das Verzeichnis `/usr/web/temp` zumindest schon existiert), aber es wird mit `warn` eine entsprechende Warnung auf die Standardfehlerausgabe, die dem error_log des Webservers entspricht, geschrieben. Sie erhalten diese Warnung also nicht im Browserfenster angezeigt.
Zur Kontrolle wird auch noch übermittelt, welche Daten in die Datei geschrieben wurden. Diese Mitteilung sehen Sie allerdings in Ihrem Browser.
Die `if`-Abfrage überprüft mit dem Dateitestoperator `-e`, ob die Datei bereits existiert. Abhängig davon ist die Reaktion des Scripts.

| Funktionen für Datum und Uhrzeit
| Funktionen für Berechnungen

© 2007 Impressum