Perl stellt ein Mechanismus zur Verfügung, der es erlaubt, verschiedenen Namensbereiche zu definieren, welche sich nicht überlappen. Dies ist die Grundlage für die Verwendung von Perl-Bibliotheken und für die Entwicklung grösserer Applikationen (Modularisierung). Ausser 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 Namensbereich 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 Files gesetzt, welches mit der require-Anweisung von einem anderen File verwendet wird.
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.
Es gibt keine spezielle Syntax für Klassen in Perl. Ein Package kann als Klasse gelten, falls sie Subroutinen zur Verfügung stellt, welche Methoden sind. Ein solches Package kann Methoden von anderen Klassen ableiten, indem sie die Namen dieser Klassen in dem @ISA-Array angibt.
package subclass;
@ISA = (baseclass);
sub new {
my $self = {};
bless $self;
return $self;
}
Weitere Informationen findet man in der perlobj-Manpage.
Ein Modul ist ein Package,
welches in einem File mit dem gleichen Namen als Bibliothek
abgespeichert ist und so gestaltet ist, dass man es
wiederverwenden kann. Das heisst, es kann einen Mechanismus
zur Verfügung stellen, der es erlaubt, einige seiner
Symbole in das Package, welches es verwendet, zu
exportieren.
Es kann aber auch als Klassendefinition aufgefasst werden,
die seine Funktionsweise via 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);
Der Array @EXPORT beinhaltet die Symbole, welche per default exportiert werden, der Array @EXPORT_OK diejenigen, welche 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, welche in den aufrufenden Namensbereich importiert werden sollen. Dies ist äquivalent zu folgenden Anweisungen:
BEGIN {require "Module.pm"; import Module; }
resp.
BEGIN (require "Module.pm"; import Module LIST; }
Alle Perl-Module sollten die Endung '.pm' haben. use
nimmt an, dass diese Endung vorhanden ist und ergänzt
den Filenamen entsprechend. Schauen wir uns noch ein letztes
Beispiel an, welches 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()!!
Wechsle in das Verzeichnis /tmp und lese die Fileliste in einen Array ein und wechsle in das Startverzeichnis zurück. Drucke den Namen des aktuellen Arbeitverzeichnisses vor und nach den Wechseln aus:
Startverzeichnis # wechseln Tmp-Verzeichnis Fileliste # zurück wechseln Startverzeichnis
Verwende dazu das Standard-Modul Cwd.pm. Beachte: Es gibt verschiedene Möglichkeiten, den Inhalt eines Verzeichnisses zu lesen:
Mache aus der letzten Uebung ein Modul, welches die Subroutine enthält und verwende ein anderes File für das Hauptprogramm. Im Hauptprogramm wird mit use das Modul importiert. Teste die zwei syntaktischen Varianten
use Module; use Module LIST;