GUI mit Perl/Tk

Tutorial

Module - Packages

Perl stellt ein Mechanismus zur Verfügung, der es erlaubt, verschiedene Namensräume zu definieren, die sich nicht überlappen. Namensräume sind die Grundlage für die Verwendung von Perl-Bibliotheken und für die Entwicklung größerer Applikationen (Modularisierung). Außer ein paar speziellen Variablen gibt es in Perl eigentlich keine globalen Variablen, da jeder Variablenname automatisch zum Package main gehört. Man kann mit der package-Anweisung den gewünschten Namensraum auswählen. Der Gültigkeitsbereich einer package-Anweisung beginnt bei der Anweisung und endet am Ende des umgebenden Blockes. Variablen eines anderen Packages können mit folgender Notation referenziert werden:

$Package::Variable
$Package'Variable   (Notation von Perl V4)

Beispiele:

{
    package MyPack;
    $foo = 100;
    $bar = 'aaa';
    $::spe = 'hallo'; # oder $main::spe
}

$foo = 200; $bar = 'bbb';

print $foo, $bar; # 200bbb
print $MyPack::foo, $MyPack::bar; # 100aaa
print $spe; # hallo 

Die package-Anweisung wird häufig an den Anfang eines Moduls gesetzt, das mit der use-Anweisung (oder auch mit require) von einem anderen Skript verwendet wird.

Übrigens: Einen praktischen Einstieg in die Erstellung von Modulen gibt die Anleitung Wie erstelle ich ein CPAN-konformes Modul?.

Konstruktoren und Destruktoren von Packages

Zwei spezielle Subroutinen werden von Perl als Konstruktoren resp. Destruktoren eines Package interpretiert. Sie heissen BEGIN resp. END.
Sobald BEGIN vollständig definiert ist, wird sie auch ausgeführt, das heisst, bevor der Rest des Files vollständig geparst ist. Damit kann ein BEGIN-Block Definitionen von Subroutinen und ähnlichem von anderen Files importieren und damit dem Parser sichtbar machen.
END wird ganz am Ende, beim Beenden des Interpreters ausgeführt.

Perl-Klassen

Es gibt keine spezielle Standard-Syntax für Klassen in Perl (sehr wohl aber diverse Module auf CPAN, wie Moose). Ein Package kann als Klasse gelten, falls es Subroutinen zur Verfügung stellt, die Methoden sind. Ein solches Package kann Methoden von anderen Klassen ableiten, indem es die Namen dieser Klassen mit use base angibt.

package MySubclass;
use base (MySuperclass);

sub new {
    my $self = {};
    bless($self);
    return $self;
}

Weitere Informationen findet man in der perlobj-Manpage.

Module

Ein Modul ist ein Package, das in einer Datei mit dem gleichen Namen als Bibliothek abgespeichert ist und so gestaltet ist, dass man es wiederverwenden kann. Das heißt, es kann einen Mechanismus zur Verfügung stellen, der es erlaubt, einige seiner Symbole in das Package, das es verwendet, zu exportieren.

Ein Modul kann auch als Klassendefinition aufgefasst werden, die seine Funktionsweise als Methoden zur Verfügung stellt, ohne Symbole explizit zu exportieren.
Oder es kann ein bisschen von beidem sein.

Will man zum Beispiel ein Modul mit dem Namen Gugus definieren, erzeugt man ein File mit dem Namen Gugus.pm und setzt folgende Zeilen an den Anfang dieses Files:

package Gugus;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(func1 func2);
@EXPORT_OK = qw($hugo @egon %mueller func3);

Das Array @EXPORT beinhaltet die Symbole, die standardmäßig exportiert werden. Das Array @EXPORT_OK beinhaltet diejenigen Symbole, die auf Anfrage exportiert werden können.

Perl Module werden mit use aufgerufen:

use Module;

oder

use Module LIST;

aufgerufen. Die Liste LIST beinhaltet die gewünschten Symbole, die in den aufrufenden Namensraum importiert werden sollen.

Nachfolgendes Beispiel bindet das Modul Data::Dumper ein und macht die Funktion Dumper im Namensraum des Skripts verfügbar:

use Data::Dumper qw/Dumper/;

Alle Perl-Module sollten die Endung '.pm' haben. use nimmt an, dass diese Dateiendung vorhanden ist und ergänzt den Dateinamen entsprechend. Schauen wir uns noch ein letztes Beispiel an, das den Unterschied zwischen use und require aufzeigt:

require "Cwd.pm";       # Cwd:: 
$here = Cwd::getcwd();
use Cwd;           # Importiere Symbole von Cwd
$here = getcwd();
use Cwd();         # Importiere leere Liste von Cwd
$here = getcwd();  # Fehler: getcwd() nicht bekannt!!
require "Cwd.pm";       # Cwd:: 
$here = getcwd();  # Fehler: kein main::getcwd()!!

An dieser Stelle ist es vielleicht interessant zu wissen, wo und welche Module auf meinem System vorhanden sind.

% perl -V     # gibt viele Einzelheiten über die Installation an
              # inklusive @INC , den Modul-Suchpfad
% perldoc perldoc  # Modulbeschreibungen

Übung 1

Wechsle in das Temp-Verzeichnis und lese die Fileliste in einen Array ein und wechsle in das Startverzeichnis zurück. Gib den Namen des aktuellen Arbeitverzeichnisses vor und nach dem Wechseln aus:

Startverzeichnis
# wechseln
Tmp-Verzeichnis
Fileliste
# zurück wechseln
Startverzeichnis

Unter Linux ist das Temp-Verzeichnis /tmp. Unter Windows ist es %TEMP%

Verwende zum Wechseln des Arbeitsverzeichnisses das Standard-Modul Cwd. Verwende für das Lesen des Verzeichnisses die Standard-Perl-Funktion readdir.

Übung 2

Mache aus der letzten Uebung ein Modul, das die Subroutine enthält und verwende ein anderes Skript für das Hauptprogramm. Im Hauptprogramm wird mit use das Modul importiert. Teste die zwei syntaktischen Varianten:

use Module;
use Module LIST;
Top