GUI mit Perl/Tk

Tutorial

Unterprogramme

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 @_ 

Parameter

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.

Rückgabewerte

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];
        }
}

Lokale Variablen mit my

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) = @_;

Lokale Variablen mit 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.


Übung

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.

Top