




Allmählich nähert sich dieses Buch seinem Ende, und Sie haben sich mit den meisten Aspekten von Perl bereits vertraut gemacht oder zumindest hineingeschnuppert. Doch mit welchem Thema man sich auch beschäftigt, immer bietet Perl alternative Möglichkeiten und weitere Lösungswege, die ich aus Platzgründen nicht alle beschreiben konnte.
Betrachten Sie deshalb dieses Kapitel als Vertiefung zum ganzen Buch. Wir werden heute eine Reihe von Themen erörtern, die ich bisher nicht angesprochen habe, weil sie entweder zu komplex oder von zu peripherer Bedeutung für die einzelnen Kapitelinhalte waren. Diese Themen umfassen:
Wenn Sie ein Perl-Skript schreiben, wird Ihre Vorgehensweise meistens so aussehen, wie bisher in diesem Buch beschrieben: Sie schreiben das Skript, speichern es in einer Datei und bedienen sich dann des Perl-Interpreters, um das Skript auszuführen. Manchmal jedoch haben Sie es mit einer wirklich einfachen Aufgabe zu tun oder aber mit einer einmaligen (oder zumindest sehr selten anfallenden) Aufgabe. Für Probleme dieser Art wäre es reine Zeitverschwendung, extra den Editor aufzurufen, nur um das eigentliche Skript zu schreiben. Abhilfe schaffen in diesen Fällen die einzeiligen Skripts von Perl, sogenannte Einzeiler.
Einzeiler sind Perl-Skripts, die Sie direkt an der Perl-Befehlszeile eingeben. Sie werden nirgends gespeichert. Haben Sie einen Fehler gemacht, müssen Sie sie neu eingeben.
  Um einen Einzeiler in Perl zu erstellen, verwenden Sie die Option -e gefolgt von dem 
Skript in Anführungszeichen:
% perl -e 'print "Dies ist ein Einzeiler\n";'
Dies ist ein Einzeiler
%
Unter Windows müssen Sie das ganze Skript in doppelte Anführungszeichen setzen und die doppelten Anführungszeichen im Skript selbst mit einem Backslash kennzeichnen:
C:\> perl -e "print \"Dies ist ein Einzeiler unter Windows\n\";"
  Arbeiten Sie mit MacPerl, so haben Sie keine Befehlszeile. Doch keine Panik! Es gibt 
im Skriptmenü einen passenden Menübefehl, der die Befehlszeile simuliert und in den 
Sie Ihren Perl-Einzeiler eingeben können. Aber auch hier müssen Sie das Wort perl, 
die Option -e und das Skript in Anführungszeichen eingeben.
  Wenn Ihr Skript mehrere Anweisungen enthält, so setzen Sie sie einfach alle in eine 
Zeile (in den meisten Unix-Shells können Sie einen Befehl auf mehrere Zeilen 
verteilen, indem Sie ein Backslash (\) an das Ende der Zeile setzen). Zur Erinnerung: 
Perl stört sich nicht an Zwischenraumzeichen (Whitespaces). Deshalb könnten Sie 
theoretisch einen unglaublich komplexen Einzeiler erzeugen, und Perl hätte trotzdem 
keine Probleme mit dessen Ausführung (vielleicht haben Sie auch schon den 
altbekannten Spruch vieler Perl-Programmierer gehört: »Ich erledige das alles in einer 
Zeile!« - was natürlich möglich ist, da man in Perl alles in einer Zeile machen kann, 
fragt sich nur, wie lang die Zeile dann wird).
Sehen Sie im folgenden einige Beispiele für einzeilige Perl-Skripts.
So drehen Sie alle Zeilen in einer Datei um:
% perl -e 'print reverse <>;' dateiname.txt
So geben Sie alle Zeilen einer Datei mit Zeilennummern aus:
% perl -e '$i=1;while(<>){print "$i: $_";$i++}' dateiname.txt
So entfernen Sie alle führenden Whitespace-Zeichen aus allen Zeilen einer Datei:
% perl -e 'while(<>){s/^\s+//g;print;}' dateiname.txt
So geben Sie eine Datei in Großbuchstaben aus:
% perl -e 'while(<>){print uc  $_;}' dateiname.txt
  Da Skripts dieser Art häufig while-Schleifen mit <> und einer Form von print 
verwenden, gibt es in Perl dafür eine Kurzform. Die Option -p erlaubt Ihnen, den 
while(<>)-Teil wegzulassen und $_ dennoch Zeile für Zeile auszugeben. Demzufolge 
könnte man das Beispiel zur Konvertierung in Großbuchstaben auch folgendermaßen 
schreiben (ob das wirklich besser ist, müssen Sie selbst entscheiden):
% perl -p -e '$_ = uc $_;' test.txt
Diese Zeile entspricht dem folgenden Code:
while (<>) {
   $_ = uc $_;
   print;
}
  Sie können die beiden Befehlszeilenoptionen auch zusammenfassen, müssen aber die 
p-Option vor die e-Option stellen:
% perl -pe '$_ = uc $_;' test.txt

-pist nicht die einzige Perl-Option, die Ihnen in Ihren Einzeilern Tipparbeit abnehmen soll. Die Option-nentspricht in etwa der Option-p, erzeugt aber keinenwhile(<>)-Schleife). Die Option-lin Kombination mit-poder-nträgt automatisch dafür Sorge, dass das Neue-Zeile-Zeichen am Ende jeder Zeile erst entfernt und dann beim Ausgeben wieder eingefügt wird. (Oder um genau zu sein,-lsetzt den Wert der Variablen$\, dem Trennsymbol für die Ausgabedatensätze, auf$/, dem Trennsymbol für die Eingabedatensätze - in der Regel das Neue-Zeile-Zeichen). Alternativ können Sie-leinen oktalen Wert als zusätzliches Argument mitgeben, der das Zeichen repräsentiert, das Sie als Trennsymbol für die Ausgabedatensätze verwenden wollen.
  Einzeiler können extrem leistungsfähig sein, wenn sie zusammen mit der Option -i 
verwendet werden. Angenommen Sie haben einen Roman geschrieben und auf 
mehrere Dateien verteilt, die alle auf die Extension .txt enden. Jetzt wollen Sie alle 
Vorkommen des Namens »Stefan« durch den Namen »Fred« ersetzen. Das einzeilige 
Perl-Skript, das dies leistet, alle Originaldateien ändert und von jeder Datei eine 
Sicherungsdatei anlegt, sieht wie folgt aus:
% perl -p -i.bak -e 's/Stefan/Fred/g' *.txt
  Die Option -i schreibt direkt in Ihre Originaldateien, so dass die neuen Versionen die 
gleichen Dateinamen tragen wie die Originaldateien. Die alten Versionen dieser 
Dateien (in denen Ihr Held noch Stefan hieß) werden in Dateien mit der Extension 
.txt.bak gespeichert. Auf diese Weise haben Sie immer noch die Möglichkeit, auf die 
alten Dateien zuzugreifen, für den Fall, dass Sie vielleicht nicht Stefan, sondern Albert 
in Fred umbenennen möchten. Seien Sie vorsichtig mit diesem Perl-Befehl - testen 
Sie ihn zuerst einmal an einer einzigen Datei, ohne Änderungen vorzunehmen. So 
können Sie sicherstellen, dass Ihr Einzeiler auch korrekt funktioniert. Sonst kann es 
Ihnen passieren, dass Sie am Ende eine ganze Reihe von .bak-Dateien restaurieren 
müssen.
Eines der größeren Themen, auf das ich in diesem Buch nicht näher eingegangen bin, betrifft die Verwendung von Perl für die objektorientierte Programmierung, kurz OOP (wäre der Titel dieses Buches Perl in 25 1/2, hätten wir es vielleicht geschafft). Glücklicherweise fällt die Einarbeitung in die objektorientierte Programmierung unter Perl nicht allzu schwer, da Perl bekannte Elemente wie Pakete, Subroutinen und Referenzen verwendet, um eine objektorientierte Programmierumgebung zu schaffen. Auf diese Weise können Sie, wenn Sie sich schon etwas mit OOP auskennen, direkt - unter Beachtung bestimmter Regeln - mit der Programmierung beginnen. Wer in der objektorientierten Programmierung noch unerfahren ist, muss sich zuerst etwas Hintergrundwissen aneignen. Irgendwelche neuen größeren Perl-Features brauchen Sie nicht zu lernen, um Ihre Kenntnisse in objektorientierter Programmierung direkt umzusetzen.
Wenn Sie mit objektorientierter Programmierung noch nicht vertraut und daran interessiert sind, objektorientiert zu programmieren, sollte Ihr erster Schritt darin bestehen, dass Sie sich die Grundkonzepte anschauen. Objektorientierte Programmierung bedeutet einfach, dass Sie das gleiche Programmierproblem aus einem anderen Blickwinkel betrachten. Alles, was Sie bisher in diesem Buch über Syntax und guten Programmierstil gelernt haben, behält seine Gültigkeit. Der Unterschied liegt darin, wie Ihr ganzes Skript organisiert ist und wie es sich verhält.
Der Grundgedanke, der der objektorientierten Programmierung zugrunde liegt, ist, dass Ihr Skript keine Sammlung von nacheinander ausgeführten Anweisungen und Subroutinen ist, sondern eine Sammlung von Objekten, die in einer vordefinierten Art und Weise miteinander interagieren. Jedes Objekt hat eine definierte Erscheinung oder Status (Variablen) und einen definierten Satz an Verhaltensweisen (Subroutinen, in OOP auch Methoden genannt). Objekte erhalten diese Verhaltens- und Statusschablonen von einer Klassendefinition. Diese Klassendefinition wiederum erbt (verwendet) oftmals die Merkmale von einer oder mehreren anderen Klassen. Wenn Sie ein objektorientiertes Skript erstellen, erzeugen Sie eine oder mehrere eigene Klassen, die Klassen und Objekte von anderen Quellen (in der Regel Module) importieren und verwenden. Wenn Ihr Perl-Skript ausgeführt wird, werden aus den verschiedenen Klassen Laufzeitobjekte erstellt, die untereinander ihre Variablen ändern und ihre jeweiligen Subroutinen aufrufen, um am Ende eine Art von Ergebnis zu liefern.
Hat Sie der obige Absatz zu Tode erschreckt, dann geraten Sie bitte nicht in Panik. In Perl können Sie sich langsam mit OOP anfreunden und bereits die ersten OOP- Konzepte nutzen, ohne gleich alle Konzepte und Techniken kennen zu müssen. Und außerdem gibt es im Netz eine Fülle von OOP-Tutorials, die Ihnen helfen, die Theorie und die verschiedenen Konzepte der objektorientierten Programmierung zu verstehen. Die folgenden Vorschläge sind ganz gute Ausgangspunkte:
http://www.progsoc.uts.edu.au/~geldridg/cpp/ finden Sie eine Reihe 
von Links zu verschiedenen Stellen mit OOP-bezogenen Informationen - nicht 
unbedingt Perl-spezifisch, aber mit einigen einführenden Tutorials.
   
 www.typerl.com). OOP-Konzepte 
lassen sich in der Regel von einer Sprache auf eine andere übertragen.
   
Sollten Sie immer noch verzagt sein, ist auch das noch kein Grund, in Panik zu verfallen. Zwar wird OOP von vielen als der Trend der Zukunft betrachtet, doch wenn Sie zufrieden damit sind, mit dem guten alten Perl weiterzuarbeiten, und niemand von Ihnen erwartet, sich in OOP einzuarbeiten, spricht nichts dagegen, sich an das Altbewährte zu halten. Denn schließlich führen viele Wege nach Rom.
Sie wissen also bereits, was ein Objekt ist und wie es sich zu einer Klasse verhält. Und Sie kennen die Begriffe Instanzvariable, Methode, Vererbung, Konstruktor, Destruktor und Kapselung. Dann lassen Sie uns diese Terminologie auf Perl übertragen.
In Perl ist eine Klasse ein Paket, und der Namensbereich, der vom Paket definiert wird, definiert die Kapselung und den Gültigkeitsbereich für diese Klasse. Variablen, die in diesem Paket definiert werden, sind Klassenvariablen (statische Variablen). Instanzvariablen werden normalerweise dadurch erzeugt, dass man eine Referenz auf einen Hash erzeugt und als Schlüssel den Namen der Instanzvariablen verwendet. Klassen- und Instanzmethoden werden beide als Subroutinen definiert. Der einzige Unterschied zwischen einer Methode und einer regulären Subroutine ist der, dass eine Methode als erstes Argument einen Klassennamen (für Klassenmethoden) oder eine Objektreferenz (für Instanzmethoden) erwartet.
  Eine Objektreferenz? Gut aufgepaßt. Das ist das einzig Neue, das Sie, soweit es Perl 
betrifft, lernen müssen, um in Perl objektorientiert programmieren zu können. In Perl 
ist ein Objekt eine Referenz auf eine Datenstruktur (in der Regel ein anonymer leerer 
Hash), die mit einer speziellen Markierung versehen wurde, so dass sie sich wie ein 
Objekt verhält und weiß, zu welcher Klasse sie gehört. Um etwas als ein Objekt zu 
markieren, verwenden Sie die vordefinierte bless-Funktion. Diese Funktion liefert 
eine Referenz auf ein Objekt zurück, die Sie dann wiederum, wie jede andere Referenz 
auch, einer Skalarvariablen zuweisen können.
  Normalerweise verwenden Sie bless in dem Konstruktor Ihrer Klasse. Der 
Konstruktor ist eine ganz normale Subroutine, die per Konvention new genannt wird. 
Die bless-Funktion übernimmt zwei Argumente: das, wofür Sie eine Objektreferenz 
erstellen wollen, und den Namen einer Klasse. Eine einfache Klassendefinition könnte 
damit wie folgt aussehen:
package MeineKlasse;
sub new {
my $klassenname = shift;
my $selbst = {};
return bless $selbst, $klassenname;
}
  In diesem Beispiel wird davon ausgegangen, dass die Klassenmethode new mit einem 
Argument aufgerufen wird: einem Klassennamen. In new selbst erzeugen wir einen 
leeren, anonymen Hash, markieren ihn mittels bless mit dem aktuellen 
Klassennamen und liefern eine Referenz auf den Hash zurück. Beachten Sie, dass new 
eine Klassenmethode ist und dass Klassenmethoden immer als erstes Argument den 
Namen der Klasse erhalten.

Sie können
blessauch mit nur einem Argument verwenden (dem Element, das mitblessmarkiert werden soll), und Perl wird den Namen der aktuellen Klasse automatisch als zweites Argument verwenden. Aufgrund der Art und Weise wie Perl jedoch mit vererbten Methoden umgeht, kann die Verwendung von nur einem Argument zu falschen Ergebnissen führen, wenn eine andere Klasse Ihren Konstruktor erbt. Allgemein möchte ich Ihnen nahelegen, sich daran zu gewöhnen,blessmit zwei Argumenten zu verwenden, und den Klassennamen der Argumentliste der Methode zu entnehmen.
  Um ein Objekt zu erzeugen und zu verwenden (aus dieser Klasse oder aus irgendeiner 
anderen Klasse), rufen Sie die Methode new zusammen mit einem Paket- (Klassen-) 
namen auf. Sie können dies in der gleichen Datei erledigen, in der auch Ihre 
Klassendefinition steht, solange Sie vorher in package main wechseln:
package main;
$obj = new MeineKlasse;
  Die Skalarvariable $obj enthält dann eine Referenz auf ein Objekt, das durch die 
Klasse MeineKlasse definiert ist. Alternativ können Sie auch die Pfeilsyntax (mit ->) 
verwenden, um den new-Konstruktor aufzurufen:
$obj = MeineKlasse->new();
  Beide Möglichkeiten, new aufzurufen, führen zum gleichen Ergebnis. Wenn Ihr new-
Konstruktor jedoch neben dem Klassennamen noch weitere Argumente benötigt, ist 
es oft leichter, das letztere Format anzuwenden:
$obj = MeineKlasse->new(12, 240, 15);
Um die Methoden aufzurufen, die in Ihrem neuen Objekt definiert sind, müssen Sie die Objektreferenz dereferenzieren. Dafür eignet sich die ->-Syntax besonders gut:
$obj->eineSubroutine('foo','bar');
Alternativ gibt es für Methoden eine Syntax, die stärker an die normale Funktionsaufruf-Syntax angelehnt ist. Dabei muss das erste Argument zu der Methode der Klassenname oder eine Objektreferenz sein:
eineSubroutine $obj, 'foo', 'bar';
Da das erste Argument hier eine Objektreferenz ist, wird Perl die Referenz für Sie dereferenzieren und die richtige Methode aufrufen.
  Sie können eine Methode auch wie eine Funktion in einem Paket aufrufen 
((Myclass::eineSubroutine(...)). Diese Vorgehensweise empfiehlt sich aber nur, 
wenn Sie genau wissen, was Sie machen. Damit untergraben Sie nämlich die OOP-
Eigenschaften der Klasse und verlieren die Fähigkeit, an eine Methodendefinition zu 
gelangen, die Ihnen über Vererbung zur Verfügung steht. Im nächsten Abschnitt 
»Instanzvariablen« erzähle ich Ihnen noch mehr zum Definieren und Aufrufen von 
Referenzen.
  Wenn Sie wie oben beschrieben Objekte erzeugen, verwenden Sie einen anonymen 
Hash als das, was Sie mit bless als Objekt markieren. Warum gerade einen Hash? 
Weil ein Hash zum Speichern und Zugreifen auf Instanzvariablen genutzt werden kann 
und Sie jedesmal eine neue Version dieser Variablen erhalten. Auf diese Weise 
werden alle internen Objektstatusinformationen in Perl-Objekten gespeichert.

In manchen OOP-Sprachen wird zwischen Instanzvariablen und Klassenvariablen unterschieden (letztere werden manchmal auch als statische Daten bezeichnet). Perl kennt an sich keine Klassenvariablen. Sie können zwar jederzeit globale Paketvariablen erstellen, die die Funktion von Klassenvariablen haben, und auf diese dann über die normale Paketsyntax
($MeineKlasse::meineKlassenVar) zugreifen, allerdings werden diese Variablen nicht vererbt und können von jedem Benutzer Ihrer Klasse beliebig geändert werden. Versuchen Sie, die Verwendung von Klassenvariablen zu umgehen und statt dessen Instanzvariablen zu verwenden.
  Im allgemeinen werden die Instanzvariablen einer Klasse in dem Konstruktor der 
Klasse definiert und initialisiert. Häufig werden Sie dabei Argumente an new 
übergeben, die die Anfangswerte dieser Klasse bilden sollen:
#!/usr/bin/perl -w
package Rectangle;
sub new {
my ($classname, $w, $h) = @_;
my $self = {};
$self->{Width} = $w;
$self->{Height} = $h;
return bless $self, $classname
}
sub area {
my $self = shift;
return $self->{Width} * $self->{Height};
}
package main;
$sq = new Rectangle (12, 20);
print "Fläche: ", $sq->area(), "\n";
  In diesem Beispiel haben wir einen Klassenkonstruktor verwendet, der zwei 
zusätzliche Argumente übernimmt - eine Breiten- und eine Höhenangabe. Auf der 
Grundlage dieser Argumente erzeugt der Konstruktor ein Rectangle-Objekt 
(Rechteck) und speichert die Werte in dem Hash des Objekts unter den Schlüsseln 
Width und Height. Des weiteren haben wir eine Methode namens area erzeugt, die 
die aktuellen Werte dieser Instanvariablen multipliziert und das Ergebnis zurückliefert.
Im allgemeinen sieht die objektorientierte Programmierung mit Instanzvariablen in Perl so aus, dass Sie zum Schreiben und Lesen dieser Variablen Methoden definieren und verwenden, anstatt die Werte der Variablen durch direkte Zuweisung zu ändern. Dies ist insbesondere bei der Vererbung von Vorteil und sorgt dafür, dass Ihre Klasse oder Ihr Objekt eine »reinere« objektorientierte Schnittstelle erhält. Sie können aber auch mit der normalen Dereferenzierungssyntax auf die Instanzvariablen zugreifen:
# kein objektorientierter Variablenzugriff
print "Width: $sq->{Width}\n";
print "Height: $sq->{Height}\n";
Wie jede ordentliche objektorientierte Programmiersprache erlaubt auch Perl die Vererbung von Klassen, die es Klassen erlaubt, die Definitionen anderer Klassen zu verwenden und zu erweitern. Wenn die Klasse B das Verhalten von Klasse A erbt, wird Klasse A als Basis- oder Superklasse und Klasse B als abgeleitete oder Subklasse bezeichnet.
  Um anzuzeigen, dass eine Klasse von einer anderen Klasse erbt, verwenden Sie das 
spezielle Array @ISA. Das Array @ISA legt fest, in welchen Klassen nach 
Methodendefinitionen gesucht wird, wenn die Definition einer aufgerufenen Methode 
nicht in der aktuellen Klasse existiert. Wenn Sie zum Beispiel eine Superklasse Katzen 
hätten, würde die Subklasse Tiger wie folgt aussehen:
package Tiger;
@ISA = qw( Katzen );
...
  Wenn eine Klasse nur von einer Superklasse erbt, ist der Aufruf von qw nicht 
unbedingt erforderlich, erleichtert aber das Hinzufügen weiterer Superklassen, falls 
man sich später für eine Mehrfachvererbung entscheidet:
package Hauskatze;
@ISA = qw( Katze Haustier );
...
  Wenn für eine Methode, die über ein bestimmtes Objekt aufgerufen wird, in der 
aktuellen Klassendefinition keine Definition gefunden wird, geht Perl das @ISA-Array 
durch und sucht in jeder der aufgelisteten Superklassen nach der betreffenden 
Methodendefinition. Gibt es zu einer Superklasse wieder weitere Superklassen werden 
diese ebenfalls durchsucht, bevor die nächste Superklasse im @ISA-Array an die Reihe 
kommt. Nehmen wir an, die Methode fressen wird für ein Objekt der Klasse 
Hauskatze aufgerufen. Zuerst wird in Hauskatze selbst nach einer Definition gesucht, 
dann in Katze und dann in allen Superklassen von Katze (falls vorhanden) und in 
deren Superklassen, bevor die Suche nach der Definition in Haustier fortgeführt wird. 
Die Definition, die zuerst gefunden wird, wird auch verwendet.
Perl vererbt nur Methoden. Um Instanzvariablen zu »vererben«, können Sie geerbte Konstruktormethoden verwenden, um einen einzigen Hash von Instanzvariablen einzurichten, der die Instanzvariablen sämtlicher Superklassen aufnimmt - plus denen, die für die aktuelle Klasse definiert wurden. (Ein Beispiel hierfür finden Sie in der Manpage perlobj.)
Das Definieren von Methoden kann in drei allgemeine Kategorien unterteilt werden:
Methoden, die von der Vererbung keinen Gebrauch machen, werden als gewöhnliche Subroutinen in der Klassen-(Paket-)Definition aufgesetzt. Die einzige Besonderheit ist das erste Argument zu dieser Subroutine, das festlegt, ob die Methode eine Klassen- oder eine Instanzmethode ist.
  Im Falle von Instanzmethoden ist das erste Argument eine Objektreferenz. 
Normalerweise wird bei Methoden dieser Art zuerst einmal die Referenz aus der 
Argumentliste extrahiert und in einer Skalarvariablen gespeichert ($self ist ein sehr 
geläufiger Variablenname, er kann aber auch beliebig anders lauten):
sub meineMethode {
   my $self = shift;
...
}
Bei Klassenmethoden ist das erste Argument einfach der Name der Klasse - nichts Besonderes, nur ein String. Auch hier werden Sie für gewöhnlich das Argument extrahieren und es in einer Skalarvariablen speichern.
  Wie sieht es jetzt aber mit Methoden aus, die je nach Argument entweder eine 
Klassen- oder eine Instanzmethode sein können. Für solche Methoden brauchen Sie 
einen Weg, wie Sie im Rumpf der Methode feststellen können, ob es sich bei dem 
ersten Argument um ein Objekt oder eine Klasse handelt. Sehr hilfreich ist in diesem 
Zusammenhang die Funktion ref:
sub klasseOderInstanz {
  my $arg = shift;
  if (ref($arg)) {
     print "Argument ist ein Objekt\n";
  } else {
     print "Argument ist ein Klassenname\n";
  }
}
  Beachten Sie, dass die ref-Funktion, wenn sie mit einer Objektreferenz als Argument 
aufgerufen wird, den Namen der Klasse zurückliefert, von der das Objekt eine Instanz 
darstellt.
Wenn Sie eine Methode aufrufen, die in der aktuellen Klasse definiert ist, wird diese Methode ausgeführt - auch wenn es weiter oben in der Vererbungskette eine gleichnamige Methode gibt. Dies ist der Weg, wie Sie Methoden definieren, die bestehende Methoden überschreiben - einfach definieren und fertig.
  Wenn Sie das Verhalten einer Methode einer übergeordneten Klasse ergänzen wollen, 
anstatt es komplett zu überschreiben, verwenden Sie das Paket SUPER, das Perl 
anweist, in den in @ISA aufgeführten Klassen nach einer Methodendefinition zu 
suchen:
sub berechnen {
   my $self = shift;
   my $sum = $self->SUPER::berechnen(); # zuerst die Superklassen
   foreach (@_) {
      $sum += $_;
   }
   return $sum;
}

SUPERwird häufig in geerbten Konstruktoren (new-Methoden) verwendet. MitSUPERkönnen Sie einen Konstruktor erzeugen, der die Vererbungskette hinaufläuft, um sicherzustellen, dass das aktuelle Objekt über alle Instanzvariablen und Initialisierungen verfügt, die es benötigt.
  Ich habe Ihnen bereits gezeigt, wie Sie Konstruktormethoden mit bless erzeugen. Sie 
können aber auch Destruktormethoden erzeugen, die ausgeführt werden, wenn alle 
Referenzen auf das Objekt gelöscht sind und das Objekt nur noch darauf wartet, von 
der Speicherbereinigung entfernt zu werden. Sie erzeugen eine Destruktormethode, 
indem Sie eine Subroutine namens DESTROY in Ihrer Klasse definieren:
sub DESTROY {
   print "Objekt löschen\n";
   ...
}
  In Verbindung mit den Methodenaufrufen gibt es in Perl eine nette Besonderheit, die 
ich Ihnen nicht vorenthalten möchte: die sogenannten selbstladenden Methoden. 
Selbstladende Methoden stellen eine Art letzte Zuflucht dar, wenn Sie für ein Objekt 
eine Methode aufrufen, für die Perl keine passende Definition finden kann. In diesem 
Fall versucht Perl, eine Methode namens AUTOLOAD aufzurufen. Die Paketvariable 
$AUTOLOAD enthält den Namen der Methode, die aufgerufen wurde (einschließlich des 
ursprünglichen Klassennamens, für den sie aufgerufen wurde). Sie können diese 
Informationen dann nutzen, um festzulegen, wie ansonsten unbekannte 
Methodenaufrufe verarbeitet werden sollen. Die Manpage perlobj enthält ein 
hervorragendes Beispiel dafür, wie man mit Hilfe einer selbstladenden Methode 
Zugriffsmethoden für Instanzvariablen simulieren kann, ohne dass man tatsächlich für 
jede Variable eine eigene Methode definieren müßte. Im folgenden finden Sie ein 
einfaches Beispiel für eine selbstladende Methode, die diese Art von Verhalten zeigt:
package Hauskatze;
@ISA = qw( Katze, Haustier );
sub new {
my $classname = shift;
return bless {}, $classname;
}
sub AUTOLOAD {
my ($self,$arg) = @_;
my $name = $AUTOLOAD;
my $iv =~ s/.*://; # Paket-Teil aus Namen entfernen
if ($arg) { # Wert setzen
$self->{$iv} = $arg;
return $arg;
} else { # kein Argument, Rückgabewert zurückliefern
return $self->{$iv};
}
}
package main;
my $cat = new Hauskatze;
$cat->color("Grau");
print "Meine Katze ist $cat->color()\n";
  In diesem Beispiel hat die Klasse Hauskatze keine Methode namens color (und wir 
gehen davon aus, dass die übergeordneten Klassen ebenfalls keine Methode dieses 
Namens haben). Wenn die Methode color aufgerufen wird, ruft Perl daher AUTOLOAD 
auf. In der Definition von AUTOLOAD erhalten wir den Namen der aufgerufenen 
Methode über die Variable $AUTOLOAD, entfernen den Paketnamen zu Beginn und 
verwenden den übriggebliebenen Methodennamen dann als Namen der 
Instanzvariablen. Wurde die Methode mit einem Argument aufgerufen, weisen wir 
diesen der Instanzvariablen zu. Andernfalls geben wir einfach den aktuellen Wert aus 
(es obliegt dem Aufrufer, undefinierte Instanzvariablen zu handhaben). Sie können 
diese AUTOLOAD-Methode genau so einfach auch für alle anderen Instanzvariablen 
verwenden - name, alter, temperament, lieblingsessen und so weiter.

Technisch gesehen, stellen
AUTOLOAD-Methoden nicht unbedingt die letzte Zuflucht dar. Zusätzlich zuAUTOLOADgibt es noch die KlasseUNIVERSAL.UNIVERSAList eine Art globale Superklasse. In ihr können Sie Ihre Zufluchtsmethoden definieren.
In Perl ist OOP kein Dogma, sondern eine optionale Möglichkeit. Sie können OOP nur sporadisch einsetzen oder die Sache gründlich angehen und OOP konsequent überall verwenden. Das hängt ganz davon ab, was am leichtesten ist und wie fanatisch Sie den Grundprinzipien der objektorientierten Programmierung anhängen.
  In vielen Fällen nutzt man die Vorzüge der objektorientierten Programmierung am 
einfachsten dadurch, dass man die verschiedenen objektorientierten CPAN-Module in 
die eigenen Skripts einbindet - ohne dass man dazu notwendigerweise die eigenen 
Skripts als einen Satz von Objekten strukturieren müßte. Erinnern wir uns noch 
einmal an die CGI-Skripts und das Modul CGI.pm von Tag 16, »Perl für CGI-Skripts«. 
Dieses Modul ist so geschrieben, dass seine Subroutinen sowohl als einfache 
Subroutinen als auch als objektorientierte Methoden verwendet werden können. 
Betrachten wir eine der Übungen, die wir am Ende der Lektion gemacht haben - 
Übung 1, ein CGI-Skript, das nur die ihm übergebenen Schlüssel und Werte ausgibt - 
und setzen wir das CGI-Modul diesmal objektorientiert ein.
Das Originalskript sehen Sie noch einmal in Listing 20.1
1: #!/usr/bin/perl -w
2: use strict;
3: use CGI qw(:standard);
4:
5: my @keys = param();
6:
7: print header;
8: print start_html('Hallo!');
9: print "<H1>Schlüssel/Wert-Paare</H1>\n";
10: print "<UL>\n";
11:
12: foreach my $name (@keys) {
13: print "<LI>$name = ", param($name), "\n";
14: }
15: print "</UL>\n";
16:
17: print end_html;
  Wir verwenden in diesem Skript vier Subroutinen aus dem CGI-Moduls: param (Zeilen 
5 und 13), die uns die gesamte Liste der verfügbaren Schlüssel und deren Werte 
liefert, header (Zeile7), um einen CGI-Header auszugeben, start_html (Zeile 8), um 
den oberen Teil einer HTML-Datei auszugeben, und end_html (Zeile 17), um den 
unteren Teil einer HTML-Datei auszugeben. Im obigen Beispiel haben wir diese 
Subroutinen als reguläre Subroutinen verwendet.
Das CGI-Modul kann aber auch als eine objektorientierte Klasse verwendet werden. Erzeugen Sie eine Instanz dieser Klasse, und Sie können die Subroutinen verwenden, als ob es sich dabei um Methoden handeln würde (was sie ja auch eigentlich sind). Alles was hierzu nötig ist, ist eine zusätzliche Codezeile und eine etwas abgeänderte Syntax für die Subroutinen (siehe Listing 20.2).
Listing 20.2: Die objektorientierte Version von paare1.pl
1: #!/usr/bin/perl -w
2: use strict;
3: use CGI qw(:standard);
4:
5: my $obj = CGI->new();
6: my @keys = $obj->param();
7:
8: print $obj->header();
9: print $obj->start_html('Hallo!');
10: print "<H1>Schlüssel/Wert-Paare</H1>\n";
11: print "<UL>\n";
12:
13: foreach my $name (@keys) {
14: print "<LI>$name = ", $obj->param($name), "\n";
15: }
16: print "</UL>\n";
17:
18: print $obj->end_html();
Sehen Sie die Unterschiede? Eigentlich sind es nur zwei:
$obj. Entsprechend den Perl-Konventionen heißt der 
Objektkonstruktor für die CGI-Klasse new.
   
 param, start_html, header und end_html - werden als 
Objektmethoden mittels der Dereferenzierungssyntax (das Objekt, -> und der 
Name der Methode) aufgerufen.
   
Und das Endergebnis? Es gibt keinen Unterschied zu der Nicht-OOP-Version. Das CGI-Modul ist so geschrieben, dass es gleichermaßen gut als normale Sammlung von Subroutinen oder als objektorientierte Klasse verwendet werden kann.
Beachten Sie, dass es sich bei diesem Beispiel nicht um ein »reines« OOP-Programm handelt. Wir haben hier keine eigenen Klassen erzeugt. Ein »wahres« OOP-Skript würde den Großteil des Codes in einer eigenen Klasse unterbringen und dort das CGI- Modul nutzen. Im Hauptteil würde kaum mehr als die Instantiierung der Klasse und die Aufrufe von ein oder zwei Methoden stehen, um das Skript in Gang zu setzen. Das ist das Gute an OOP in Perl. Sie müssen nur so viel objektorientierte Programmierung einsetzen wie nötig. Im Gegensatz zu anderen strengeren OOP-Sprachen, müssen Sie Code, der für OOP ungeeignet erscheint, nicht unbedingt in Objekte pressen.
In Anbetracht der Tatsache, dass Perl ein Akronym für Practical Extraction and Report Language (Praktische Extraktions- und Reportsprache) ist, mag es Sie überraschen, dass bisher in diesem Buch zwar viel über das Extrahieren geschrieben wurde, aber kaum etwas über das Protokollieren. Für letzteres gibt es die Formate: zur Ausgabe von formatierten textbasierten Protokollen über Informationen, die Sie vorher gelesen, verarbeitet oder anderweitig malträtiert haben.
  Warum wird dieses Thema erst jetzt gegen Ende des Buchs angesprochen? Ein großer 
Teil der Ausgabe von Perl-Skripts erfolgt heutzutage - als Ergebnis von CGI-Skripts - 
im HTML-Format und nicht mehr im Nur-Text-Format. Wenn Sie also davon 
ausgehen, dass Sie Perl hauptsächlich für CGI einsetzen werden, ist HTML für die 
Ausgabe besser geeignet als reiner Text. Wenn Sie aber vornehmlich mit einfacher 
Textausgabe arbeiten, sollten Sie sich unbedingt mit den Formaten befassen, vor 
allem auch unter dem Aspekt, dass print-Anweisungen ziemlich umständlich sind, um 
eine ordentliche und übersichtliche Präsentation Ihrer Ausgabe sicherzustellen.
  Die Idee hinter den Formaten ist die, dass Sie mit Hilfe der format-Funktion eine 
spezielle Schablone (Template) deklarieren, die festlegt, wie Ihre Ausgabe auszusehen 
hat, und dann mit der write-Funktion und einem Datei-Handle diese Schablone auf 
die Daten anwenden. Als Ergebnis werden die Platzhalter in der Schablone durch 
einen Satz von Werten aus der gegebenen Datenmenge ersetzt. Die Schablone legt 
die Position einer jeden Datenspalte sowie ihre Breite und Ausrichtung fest. Zusätzlich 
steht Ihnen eine Reihe von speziellen Perl-Variablen für die Größe einer Seite (in 
Zeilen), den Header (Kopfbereich), der oben auf jeder Seite erscheinen soll, und die 
aktuelle Seitenzahl zur Verfügung. Insgesamt können Sie so für jede beliebige Art von 
Daten Protokolle mit Ganzseiten-Textformatierung erzeugen.
  Schablonen werden mit Hilfe der Funktion format deklariert. Schablonennamen 
verhalten sich wie Subroutinen- oder andere Variablennamen, sie unterliegen den 
gleichen Regeln zur Namensgebung und geraten nicht mit den Namen anderen Arten 
von Variablen in Namenskonflikt. Eine format-Deklaration enthält einen Namen, eine 
Reihe von Bildzeilen, die festlegen, wie das Format aussehen soll, und einen Satz an 
Variablen, die die Daten festlegen, die in die Schablone passen sollen. Das Format 
endet mit einem einzelnen Punkt in einer eigenen Zeile. Im folgenden sehen Sie ein 
Beispiel für ein einfaches Format, das eine Reihe von Firmen mit Börsenticker-
Symbolen, Höchstpreisen, Niedrigstpreisen und Abschlußpreisen ausgibt:
format STDOUT =
@<<<<<<<<<<<<<<<<<<@||||@|||||@|||||@|||||
$name, $sym,$high,$low, $current
.
  Bildzeilen enthalten Symbole für einfache, einzeilige Spalten (@) oder einfache, gefüllte 
Textspalten (^). Jede Zeile kann auf vielfältige Weise mit verschiedenen  Symbolen (<, 
|, >, #) ausgerichtet werden (links, zentriert, rechts, numerisch). Die Variablen geben 
an, welche Daten an den einzelnen Positionen im Format stehen sollen, wenn die 
Zeile ausgegeben wird. Wenn Sie use strict verwenden, müssen Sie diese Variablen 
vorher mit my deklarieren, bevor Sie sie in dem Format verwenden können.
  Um die formatierten Daten an ein Datei-Handle auszugeben, verwenden Sie die 
write-Funktion:
write STDOUT;
  Beachten Sie, dass der Name des Formats mit dem Namen des Datei-Handles, an das 
die Ausgabe erfolgt, übereinstimmen muss (obwohl Sie dies mit dem Modul 
FileHandle ändern können). In unserem Fall habe ich das Standard-Datei-Handle 
STDOUT verwendet.
  Betrachten wir noch ein Beispiel. Unsere Daten sind eine einfache Aufgabenliste, 
wobei der Datensatz aus den folgenden Feldern besteht: Zeitpunkt der Fertigstellung, 
Priorität der Aufgabe (1 bis 5), ob erledigt oder nicht (0 oder 1) und einer 
Textbeschreibung der Aufgabe (ein String von ungefähr 40 Zeichen oder weniger). 
Diese Daten sind in einer Datei gespeichert und werden in ein Array von Hashes 
(@data) eingelesen (siehe gestrige Lektion). Ihr Skript soll unter anderem dazu in der 
Lage sein, die Aufgabenliste nach Prioritäten sortiert in einem ansprechenden Format 
auszugeben. Eine entsprechende Ausgabe könnte zum Beispiel wie folgt aussehen:
Fertig? Fälligkeit Priorität Beschreibung
------------------------------------------------------------
Nein 23.10.1998 1 Kapitel 21 beenden
Nein 31.10.1998 1 Kapitel 20 beenden, überarbeiten
Nein 05.01.1999 2 Treffen mit Fred zum Essen
Ja 05.12.1998 3 Punkt 3
Nein 10.01.1999 5 Pyramide bauen
  Um diese Daten ohne Formate auszugeben, würden Sie eine foreach-Schleife 
aufsetzen, die jeden Datensatz durchläuft, daraus eine Zeile aufbaut und diese dann an 
den Datei-Handle ausgibt. Da Sie keine Formate verwenden, müssen Sie selbst die 
Abstände zwischen den Daten kontrollieren, um sicherzustellen, dass die Daten 
korrekt ausgerichtet werden. Mit Formaten ist die ordentliche Ausrichtung der Daten 
wesentlich einfacher.
  Um die Daten zu formatieren und auszugeben, überlegen wir zuerst, wie die Ausgabe 
mit der format-Deklaration aussehen soll. Genau genommen verwenden wir zwei 
format-Deklarationen: eine einfache Nur-Text-Deklaration für den Header und eine 
für die Datenzeilen. Außerdem deklarieren wir schon einmal unsere Formatvariablen, 
damit uns use strict keinen Ärger macht:
my ($done, $date, $prior, $desc); # Formatvariablen;
format STDOUT_TOP =
Fertig? Fälligkeit Priorität Beschreibung
------------------------------------------------------------
.
format STDOUT =
@|||| @<<<<<<<<< @| @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$done, $date, $prior, $desc
.
  Die erste format-Deklaration (für STDOUT_TOP) ist eine besondere Art von Format, die 
einen Header für die Seite definiert. Header haben per definitionem den gleichen 
Namen wie das normale Format (hier STDOUT) plus dem angehängten _TOP. Sie 
könnten diesen Test als normale print-Anweisung ausgeben, aber formatierte Header 
haben den Vorteil, dass sie bei einem mehrseitigen Ausdruck auf jeder Seite 
automatisch gleich ausgegeben werden. Ich persönlich finde, dass sie das Formatieren 
stark vereinfachen, deshalb nehme ich sie meistens mit auf.
  Kommen wir jetzt zu dem interessanteren, dem zweiten Format, das unsere 
eigentliche format-Deklaration enthält. Hier definieren wir die Breite und Ausrichtung 
all unserer Spalten: done und prior sind zentriert (beachten Sie das |-Zeichen), date 
und desc sind links ausgerichtet (<-Zeichen). Die Anzahl der Ausrichtungszeichen legt 
die Anzahl der Zeichen für die Spalte fest. Weisen die Daten mehr Zeichen auf, als die 
Spalte Zeichen aufnehmen kann, werden diese abgeschnitten.
Nachdem die Formate definiert sind, besteht der zweite Schritt darin, die Daten in einer Schleife zu durchlaufen und auszugeben. Doch zuerst sortieren wir die Datensätze nach ihrer Priorität:
my @sorteddata = sort { $a->{'prior'} <=> $b->{'prior'} } @data;
Anschließend durchlaufen wir die Daten und geben sie aus:
foreach (@sorteddata) {
    my %rec = %$_;
   if ($rec{'fertig'}) {
        $done = 'Ja';
   } else {
        $done = 'Nein';
    }
    $date = $rec{'datum'};
    $prior = $rec{'prior'};
    $desc = $rec{'desc'};
    write STDOUT;
}
  Für jeden Teil jedes Datensatzes weisen Sie den temporären Variablen aus dem 
Format die auszugebenden Daten zu (die Variablen $done, $date, $prior und $desc). 
Die Daten für die Variable $done haben eigentlich die Werte 0 oder 1. In unserem 
Beispiel ersetzen wir diese Werte durch Ja oder Nein, um das Ergebnis anschaulicher 
zu machen.
  Nachdem alle Variablen gesetzt wurden, besteht der letzte Schritt aus einer write-
Anweisung, die das entsprechende Format verwendet, um eine Zeile von Daten 
auszugeben, und dann zum nächsten Datensatz in der Zeile weitergeht.
  Weitere Informationen zu  den Formaten finden Sie in der perlform-Manpage. Es 
lohnt sich auch, einen Blick auf die formatspezifischen Perl-Variablen in der perlvar-
Manpage zu werfen, wo Format-Header, Seitenzahlen und anderes beschrieben sind. 
Schließlich gibt es noch das FileHandle-Modul, das Ihnen eine objektorientierte 
Schnittstelle zu den Datei-Handles und den Formaten bietet und die Arbeit mit vielen 
der in Perl definierten Elemente zur Verwaltung mehrerer Formate und Datei-Handles 
erleichtert.
Netzwerke waren schon seit jeher eine Stärke von Unix, und Perl wäre schlecht beraten, wenn es nicht Zugriff auf die Netzwerk-Features von Unix bieten würde - insbesondere die TCP- und UDP-Sockets. Perl stellt eine Reihe von eigenen Funktionen für die Arbeit mit Sockets bereit (siehe Tabelle 20.1), die das gleiche Verhalten aufweisen wie ihre C-Gegenstücke. Wenn Sie in socketbasierter Programmierung bereits Erfahrung sammeln konnten, werden Ihnen diese Funktion vertraut vorkommen. Darüber hinaus können Sie das Socket-Modul nutzen, das Ihnen Zugriff auf die allgemeinen Socket-Strukturdefinitionen in C bietet.
Die Verwendung von Sockets in Perl hat jedoch auch seine Einschränkungen. Zum einen stehen Ihnen die meisten der Socket-Features von Perl nur unter Unix zur Verfügung. Unter Windows oder auf Macintosh-Rechner müssen Sie auf die entsprechenden Elemente von Win32 oder MacPerl zurückgreifen, wodurch Ihr Skript nicht mehr so portabel ist. Außerdem gilt es zu bedenken, dass die Chancen meist sehr gut stehen, dass die Aufgaben, die Sie mit Hilfe der Sockets erledigen wollen, bereits als Modul vorhanden sind - es sei denn, Sie wollen irgendein Netzwerkprotokoll implementieren, das nicht dem Standard entspricht. So lohnt es sich kaum, irgendwelche Teile für einen Webserver oder Webbrowser aufzusetzen, da es hinreichend Module gibt, die Ihnen diese Arbeit bereits abgenommen haben. Alles, was Sie tun müssen, ist, diese Module zu nutzen. Morgen werden wir uns hierzu ein Beispiel anschauen, das von den besonders nützlichen Modulen der LWP (Bibliothek für WWW-Zugriff in Perl) Gebrauch macht.
Suchen Sie im CPAN, vor allem im Abschnitt zu den Netzwerken, nach Modulen, die für einen Großteil der Netzwerkaufgaben, die Sie erledigen müssen, fertige Lösungen parat haben. Sollten Sie hier nicht fündig werden, schlagen Sie in der perlipc- Manpage nach, in der Sie weitere Informationen darüber finden, wie man Sockets verwendet (einschließlich einfacher Client- und Server-Beispiele).
In Tabelle 20.1 finden Sie die vordefinierten Funktionen für Sockets. Details zu diesen Funktionen befinden sich in der perlfunc-Manpage.
Tabelle 20.1: Socket-Funktionen
POD (ein Akronym für Plain Old Documentation, übersetzt mit »einfache, alte Dokumentation«) ist eine einfache Formatiersprache zum Erstellen von Dokumentationen zu Ihren Perl-Skripts oder -Modulen. In der Regel nehmen Sie diese Dokumentation direkt in Ihre Skriptdatei mit auf. Auf diese Art und Weise halten Sie das Skript und seine Dokumentation zusammen und müssen nicht beides getrennt warten. (Perl wird den POD-Inhalt einfach ignorieren, wenn Sie Ihre Skripts ausführen).
  Um sich den POD-Inhalt Ihres Skripts (oder die POD-Dateien, die nur den POD-Inhalt 
enthalten) anzuschauen, können Sie das Skript perldoc verwenden (wird mit Perl 
ausgeliefert), mit dem sie den Text der Dokumentation auf Ihrem Bildschirm anzeigen 
lassen können. Sie können aber auch einen Übersetzer verwenden, der die POD-
Dateien in ein anderes Format konvertiert - zum Beispiel pod2text für Textdateien, 
pod2html für HTML, pod2man für nroff-formatierte Manpages oder pod2latex für 
LaTeX-Formatierung. Bisher werden Sie wahrscheinlich perldoc verwendet haben, 
um die verschiedenen Teile der Perl-Dokumentation (im POD-Format) online 
einzusehen.
POD ist keine vollständige Textformatiersprache wie troff, LaTeX oder HTML. Wenn Sie also Ihre Skripts mit einer Unmenge an aufwendig formatierten Dokumentationen versehen wollen, sind Sie besser beraten, wenn Sie auf ein anderes Format zurückgreifen und Ihre Dokumentationsdateien getrennt von Ihren Skripts halten. POD-Dateien haben jedoch im allgemeinen den Vorteil, dass sie auf verschiedenen Plattformen und mit verschiedenen Systemen gelesen werden oder en passant in andere geläufigere Formate konvertiert werden können.
Beispiele für POD-Texte finden sich in fast jedem öffentlich verfügbaren Skript oder Modul, das mit Perl ausgeliefert wird oder aus dem CPAN heruntergeladen werden kann. Wenn Ihnen die nachfolgenden Ausführungen zu den POD-Dateien nicht genügen, finden Sie weitere Informationen in der perldoc-Manpage.
POD-formatierter Text besteht aus Befehlsabsätzen und normalen Absätzen. Befehlsabsätze enthalten einfache Formatierungsanweisungen und etwas Text. Normale Absätze enthalten den eigentlichen Text. Sie können aber auch Befehle zur Zeichenformatierung in die normalen Absätzen mit aufnehmen.
Befehlsabsätze stehen in eigenen Zeilen und beginnen mit einem Gleichheitszeichen. Einige Befehlsabsätze weisen auch Text auf, der sich direkt an den Namen des Absatzes anschließt. Das Ende eines Befehlsabsatzes bildet eine leere Zeile.
  Für Überschriften verwenden Sie die Befehlsabsätze =head1 und =head2, denen sich 
direkt der Text für die Überschrift anschließt. Diese Überschriften entsprechen in etwa 
den Tags <H1> und <H2> in HTML oder dem .SH-Tag in troff oder nroff.
  Für Listen und andere eingerückte Elemente gibt es die Befehle =over, =item und 
=back. Mit =over beginnen Sie eine Liste, wobei eine optionale Zahl angibt, um wie 
viele Leerzeichen die Liste eingerückt werden soll. Jedes Listenelement beginnt mit 
einem =item-Tag und einem optionalen Zeichen, das das Symbol oder die Zahl vor 
diesem Element darstellt (Sie müssen sich selbst um die Numerierung kümmern, da 
diese nicht automatisch erfolgt). Am Ende der Liste heben Sie die mit =over 
eingeleitete Einrückung mit =back wieder auf.
  Normale Absätze werden als einfache Absätze eingegeben, ohne sie mit 
irgendwelchen Befehlen zu kennzeichnen. Absätze, die ohne Whitespace-Zeichen 
beginnen, werden in der Regel so formatiert, dass sie die Seitenbreite füllen (wie <P> 
in HTML). Absätze mit einer Einrückung am Anfang werden unverändert 
übernommen (wie <PRE> in HTML). Alle Absätze müssen mit einer leeren Zeile enden.
In den Absätzen können Sie Zeichenformatierungscodes und Links mit aufnehmen, um ein bestimmtes Wort hervorzuheben oder einen Link einzufügen (der zu einer anderen Perl-bezogenen Manpage wie perlfunc oder ähnlichem führt). Im folgenden sehen Sie einige der geläufigeren Zeichenformate:
I<text> gibt das Wort text kursiv aus.
   
 B<text> gibt das Wort text fett aus.
   
 C<text> faßt text als Code auf.
   
 &escape; ersetzt den Escape-Code durch ein Sonderzeichen. Die Escape-Codes 
sind mit den HTML Escape-Codes für Akzente und andere Sonderzeichen 
weitgehend identisch.
   
 E<escape>; identisch mit &escape.
   
 L<manpage> erzeugt einen Link (oder einen textuellen Querverweis) auf eine 
Manpage; so erzeugt zum Beispiel L<perlfunc> eine Verbindung zu der perlfunc-
Manpage. Sie können auch einen Link zu einem speziellen Abschnitt in einer 
Manpage herstellen.
   
  Um Text einzubetten, der in einer anderen Formatiersprache formatiert vorliegt - zum 
Beispiel HTML oder troff - gibt es ebenfalls Befehle: =for, =begin und =end. Text, 
der für bestimmte Formatiersprachen formatiert wurde, wird von dem speziellen 
Übersetzer unverarbeitet ausgegeben (der Übersetzer pod2html wird zum Beispiel 
formatiertes HTML direkt in die Ausgabe kopieren) und ansonsten einfach ignoriert. 
Verwenden Sie eingebettete Formatierungen, um in speziellen Fällen eine 
eingeschränkte Formatierung vorzunehmen.
  Sie können POD-formatierten Text sowohl in einer eigenen Datei (in der Regel als 
Datei mit der Extension .pod) speichern oder ihn in Ihre Skript-Dateien integrieren, 
wo er schnell geändert und aktualisiert werden kann.
  Um POD-Text in ein Skript aufzunehmen, markieren Sie den Anfang des POD-
Textes mit einem beliebigen POD-Befehl (normalerweise =head1, obwohl auch =pod 
den Anfang eines POD-Textes anzeigen kann). Schließen Sie den POD-Text mit =cut 
ab. Auf diese Weise teilen Sie Perl mit, wann die Unterbrechung zu Ende ist und der 
Text weiter nach Code geparst werden kann.
  POD-Text wird in der Regel am Anfang oder am Ende eines Skripts eingefügt. Sie 
können ihn aber auch irgendwo an einer beliebigen Stelle in Ihr Skript einfügen, zum 
Beispiel um das Verhalten einer Subroutine direkt über dem Code der Subroutine zu 
beschreiben. Solange Sie Ihren POD-Text mit einem Befehlsabsatz und =cut starten 
und enden, hat Perl keine Probleme damit.
  Wenn Sie einen POD-Text an das Ende einer Datei setzen und eine __END__-
Markierung verwenden (wie es zum Beispiel beim Erzeugen von Modulen vorkommt), 
müssen Sie darauf achten, dass eine Leerzeile nach dem __END__ kommt.
  Ein weiteres nützliches Feature von Perl, das anderen Sprachen abgeschaut wurde, ist 
die Fähigkeit, einen String zur Laufzeit des Skripts als Perl-Code aufzufassen und 
auszuführen. Bewerkstelligt wird dies durch die Funktion eval, die einen String oder 
Block als Argument übernimmt und den darin enthaltenen Perl-Code kompiliert und 
ausführt, so als wenn er in einer Datei stehen oder als Perl-Einzeiler ausgeführt würde 
- und das alles innerhalb eines gerade laufenden Perl-Skripts.
  Warum ist diese Funktion so nützlich? Aus einer Vielzahl von Gründen. Einer davon 
ist, dass Sie damit anspruchsvolle Strukturen und Funktionsaufrufe aufbauen können, 
ohne extensiv in if-else-Anweisungen verzweigen zu müssen: Stellen Sie den 
aufzurufenden Code aus aneinandergehängten Strings zusammen, und rufen Sie dann 
eval auf, um den String auszuführen. Es ist auch möglich, andere Dateien, die Perl-
Code enthalten, von einem Perl-Skript aus einzulesen und auszuführen - ähnlich der 
Funktionsweise von use und require, jedoch immer zur Laufzeit Ihres Skripts (genau 
genommen ist require semantisch identisch mit eval, plus einigen Extraoptionen 
zum Suchen und Neuladen von Dateien). Des weiteren ist es möglich, Code bei 
Bedarf en passant auszuführen - der Perl-Debugger macht zum Beispiel in seiner 
Option zur Codeausführung davon Gebrauch. Oder Sie könnten mit Hilfe von eval 
einen Interpreter für Ihre eigene Sprache schreiben.
  Mit Hilfe der eval-Funktion von Perl kann man Code vor der eigentlichen Ausführung 
testen und anschließende Fehler und ungewöhnliche Bedingungen, die aus der 
Ausführung des Codes resultieren, abfangen. Diese Möglichkeit wird in anderen 
Sprachen oft als Ausnahmenbehandlung bezeichnet. Wenn Sie zum Beispiel testen 
möchten, ob eine bestimmte Perl-Funktion - zum Beispiel fork - auf dem aktuellen 
System zur Verfügung steht, könnten Sie innerhalb von eval ein einfaches Beispiel 
ausprobieren, schauen, ob es funktioniert, und wenn ja, mit dem Skript und fork 
fortfahren. Scheitert eval, führen Sie einen alternativen Code aus. Die 
Ausnahmebehandlung mit eval ermöglicht eine robustere Fehlerprüfung und -
behandlung in Ihren Skripts.
  Eine Beschreibung von eval finden Sie in der perlfunc-Manpage.
Unter Internationalisierung, manchmal auch I18N genannt, versteht man die Verallgemeinerung von Skripts oder Programmen, so dass diese leicht in eine andere Sprache oder einen Dialekt übertragen oder übersetzt werden können. Von Lokalisierung, L10N, spricht man, wenn man eine internationalisierte Version eines Skripts nimmt und in einer speziellen Sprache zum Laufen bringt. Die Internationalisierung beginnt mit einfachen Maßnahmen - zum Beispiel alle Textstrings, die ein Skript verwendet, separat aufzubewahren, um diese ohne Änderungen am Perl-Code übersetzen zu können. Andere Dinge - die Arbeit mit anderen Zeichensätzen als dem Englischen ABC, die Verwendung anderer Sortier- und Vergleichsfunktionen für Texte, das Formatieren von Zahlen - können über die Verwendung des Lokale-Moduls von Perl gesteuert werden.
Weitere Informationen zur Anwendung und Verwaltung von Perl-Lokalen zur Erzeugung internationalisierter (oder lokalisierter) Skripts finden Sie in der perllocale- Manpage.
Angenommen Sie schreiben ein Perl-Skript, das von Menschen ausgeführt wird, die Sie nicht kennen und denen Sie auch nicht besonders trauen - zum Beispiel wenn Sie eine Multi-User-Unix-Maschine verwalten oder wenn Ihr Skript für CGI verwendet wird. Da Sie denjenigen, der Ihr Skript ausführt, nicht kennen, könnte diese Person theoretisch feindliche Absichten hegen und Ihr Skript nutzen, um auf irgendeinem Weg autorisierten Zugriff auf Ihr System zu erhalten oder es in irgendeiner Weise zu mißbrauchen oder zu schädigen.
  Wie können Sie verhindern, dass ein bösartiger Benutzer Ihr Skript mißbraucht oder 
Schaden anrichtet? Sorgfältige Programmierung ist eine Möglichkeit - zum Beispiel 
vorher prüfen, ob eine Eingabe irgendwelche heiklen Daten enthält, bevor sie einem 
system-Funktionsaufruf oder schrägen Anführungszeichen übergeben wird. Doch 
manchmal ist es schwierig, zu entscheiden, welche Daten unsicher sind, manchmal 
vergißt man, diese Prüfungen durchzuführen. In all diesen Fällen ist der Taint-Modus 
sehr hilfreich.
  Der Taint-Modus wird in Perl mit der Option -T aktiviert. (Er wird außerdem 
automatisch ausgeführt, wenn sich die Benutzer- oder Gruppen-ID des Skripts von der 
Benutzer- oder Gruppen-ID der Person unterscheidet, die das Skript ausführt - zum 
Beispiel setuid-Skripts auf Unix-Systemen). Ist der Taint-Modus aktiviert, überwacht 
Perl die Daten, die in Ihr Skript gelangen - aus der Umgebung, als 
Befehlszeilenargumente oder als Daten von einem Datei-Handle (einschließlich der 
Standardeingabe). Wenn Sie versuchen, diese Daten dazu zu nutzen, irgend etwas 
außerhalb Ihres Skripts zu manipulieren, bricht Perl sofort ab. Um diese Daten 
trotzdem zu nutzen, müssen Sie Ihr Skript so schreiben, dass diese Daten teilweise 
geändert oder extrahiert werden - wodurch verhindert wird, dass unerwartete Daten 
unbemerkt durch das Skript hindurchrutschen.
Mit anderen Worten, der Taint-Modus ist kein eigener Sicherheitsmechanismus, aber er zwingt Sie, beim Schreiben Ihres Codes die Sicherheit immer im Auge zu behalten. Wenn Ihre Skripts zum Beispiel in einer unsicheren Umgebung ausgeführt werden, kann der Taint-Modus Ihnen helfen, sicherzustellen, dass Ihre Skripts nicht zu einladenden Sicherheitslecks in Ihrem System werden.
  Weitere Informationen zum Taint-Modus und zur Sicherheit in Perl finden Sie in der 
perlsec-Manpage. Wenn Sie allgemeinere Auskünfte zum Thema Sicherheit und CGI 
benötigen, schauen Sie doch mal in den häufig gestellten Fragen (FAQs) zur Sicherheit 
im WWW unter http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html 
nach.
Wenn Ihnen speziell die Sicherheit Ihrer Skripts am Herzen liegt, sollten Sie Penguin aus dem CPAN ausprobieren. Penguin stellt eine Umgebung bereit, mit der es möglich ist, Codefragmente zu verschlüsseln und digital zu signieren, bevor sie an andere Sites verschickt werden. Am Zielort entschlüsselt Penguin diese Daten wieder und prüft die Zuverlässigkeit dieses Codes vor seiner Ausführung. Und selbst dann führt Penguin den Code noch innerhalb streng kontrollierter Grenzen aus. Betrachten Sie Penguin einfach als ein Gegenstück zu Javas Mechanismus zum Signieren von Applets und der anschließenden Ausführung innerhalb eines geschlossenen, sicheren »Sandkastens«. Im CPAN finden Sie ausführliche Informationen über Penguin.
PerlScript - Teil der ActiveState-Version von Perl für Windows - ist eine Skripting- Maschine für ActiveX-Komponenten. Mit PerlScript können Sie Perl als Skript- Sprache in jeden ActiveX-Skripting-Host verwenden - zum Beispiel im Internet Explorer, IIS oder in einem beliebigen Webserver oder sogar im Windows Scripting Host (WHS) von Microsoft selbst.
Microsofts Skripting-Maschinen für ActiveX-Komponenten unterstützen per Vorgabe VBScript- und JavaScript-Skripting-Maschinen. Diese Sprachen sind zwar für die meisten Zwecke vollkommen ausreichend, doch kann Ihnen Perl in vielen Fällen weitere und leistungsstärkere Optionen bieten. Außerdem ist es für Programmierer, die bereits mit Perl vertraut sind, ein unschätzbarer Vorteil, wenn Sie einfach mit Perl weiterarbeiten können, anstatt zu anderen Sprachen wechseln zu müssen.
Sie können mit PerlScript auch für das Web programmieren und Perl-Skripts in Webseiten einbetten, und das sowohl clientseitig (Webbrowser) als auch serverseitig (Webserver) - so wie man ansonsten JavaScript- und VBScript-Skripts oder ASP- Seiten (Active Server Pages) nutzt.
  PerlScript läßt sich auch mit dem Windows Scripting Host verwenden. Dadurch haben 
Sie die Möglichkeit, verschiedene Aspekte des Windows-Systems über Skripts zu 
steuern (dient als Ersatz für die alten DOS-Batch-Dateien). Zur Zeit gibt es den 
Windows Scripting Host standardmäßig nur zusammen mit Windows 98. Er läßt sich 
aber für Windows 95 und Windows NT von msdn.microsoft.com/scripting 
herunterladen und installieren.
PerlScript wird automatisch mit der ActiveState-Version von Perl für Windows installiert. Sie können es aber auch als eigene Komponente von der ActiveState- Webseite herunterladen (Sie müssen allerdings eine Version von Perl für Windows installiert haben).
  Weitere allgemeine Informationen zu ActiveX-Skripting finden Sie unter http://
msdn.microsoft.com/scripting. Details zu PerlScript lassen sich in der 
Dokumentation zu PerlScript unter http://www.activestate.com/activeperl/docs/
perlscript.html oder in dem ausgezeichneten »Complete Guide to PerlScript« 
(vollständiger PerlScript-Führer) von Matt Sargeant unter http://
www.fastnetltd.ndirect.co.uk/Perl/Articles/PSIntro.html nachlesen.
  Eine Perl-Erweiterung ist ein Weg, eine externe Bibliothek, in der Regel in C 
geschrieben, in Perl-Skripts einzubinden. Wenn Sie eine Perl-Erweiterung erzeugen, 
erzeugen Sie sozusagen einen speziellen Code, der es Ihnen ermöglicht, diese externe 
Bibliothek wie ein beliebiges Perl-Modul mit use in Ihre Perl-Skripts zu importieren. 
Wenn Sie genau hinschauen, werden Sie feststellen, dass viele der Perl-Module im 
CPAN sowohl Perl-Code als auch Perl-Erweiterungen verwenden.
  Für die Erzeugung einer Perl-Erweiterung müssen Sie eine Sprache namens XS 
verwenden, die den »Kleber« zwischen Perl und C bereitstellt (Perl-Erweiterungen 
werden in Anlehnung an die XSUB-Funktion in der XS-Sprache manchmal auch 
XSUBs genannt). Sie können XS-Dateien selbst schreiben oder sie aus einer 
bestehenden C-Bibliothek erzeugen. Außerdem gibt es besondere Make-Dateien, die 
erstellt oder erzeugt werden müssen, damit am Ende alles zusammenpaßt (eine Make-
Datei ist ein Skript, das verwendet wird, um ein Projekt zu kompilieren und die 
Abhängigkeiten zwischen mehreren Dateien eines Projekts zu verwalten).
  In der Perl-Distribution findet sich eine Reihe von Tools und Modulen, die das 
Entwikkeln von Perl-Erweiterungen vereinfachen - einschließlich Tools, um durch 
Erzeugung von XS-Dateien bestehende C-Bibliotheken in Perl einzubinden oder um 
C-Code aus XS-Dateien zu erzeugen. Besonders erwähnenswert sind in diesem 
Zusammenhang die Module des ExtUtils-Pakets, besonders ExtUtils::MakeMaker 
(die Ihnen helfen, Make-Dateien zu erzeugen).
  Bevor Sie damit beginnen, Perl-Erweiterungen zu erzeugen, sollten Sie über 
ausreichend Hintergrundwissen zu der Entwicklung von Perl-Modulen verfügen. 
Dieses Hintergrundwissen können Sie sich in der perlmod-Manpage aneignen. Eine 
Einführung in die Erzeugung von Erweiterungen finden Sie in der perlxstut-Manpage. 
Des weiteren sollten Sie einen Blick in perlxs (das XS-Referenzhandbuch), h2xs (ein 
Skript zum Konvertieren von C-Headerdateien in XS-Dateien) und perguts (für 
interne Perl-Funktionen) werfen. Die POD-Dateien in den verschiedenen ExtUtils-
Modulen enthalten Erläuterungen, wie diese Module anzuwenden sind.
Perl 5.005 wurde während der Arbeit an diesem Buch herausgebracht. Ich habe mich bemüht, auf alle Unterschiede und neuen Teile von Perl hinzuweisen, die für Ihre Arbeit mit der neuen Version von Bedeutung sein könnten. Für den Großteil von Perl sind allerdings nur geringfügige Unterschiede zwischen der Perl-Version 5.005 und der früheren Version 5 zu verzeichnen. Radikale Änderungen sollten Ihnen eigentlich nicht auffallen. Wenn Sie aber bereits über Perl 5.005 verfügen und gern etwas herumspielen wollen, finden Sie in dieser Version eine Reihe von neuen Optionen. Einige davon, die bisher im Buch noch keine Erwähnung fanden, möchte ich Ihnen kurz vorstellen.
  Die wahrscheinlich bedeutendste Änderung in Perl 5.005 ist der Einsatz von 
Threading. Rufen Sie sich dazu noch einmal Kapitel 18, »Perl und das 
Betriebssystem«, in Erinnerung. Dort habe ich die fork-Funktion und den Einsatz von 
Prozessen behandelt und allgemein konstatiert, dass die Prozeßfähigkeiten der Unix-
Version von Perl sich nur schwer auf andere Plattformen übertragen lassen. 
Threading soll dieses Problem jetzt lösen. Sie können damit mehrere gleichzeitig 
laufende Threads erzeugen, die unabhängig voneinander gestartet und gestoppt 
werden können. Wichtiger noch ist jedoch die Tatsache, dass Threading in der Perl-
Sprache plattformübergreifend unterstützt wird, was bedeutet, dass ein für Unix 
geschriebenes komplexes Skript mit mehreren Threads sich genausogut unter 
Windows oder auf einem Macintosh-Rechner ausführen läßt. Perls Thread-System ist 
in dem Thread-Modul definiert, das man einbinden muss, um mit Threads arbeiten zu 
können. Beachten Sie, dass sich die Thread-Unterstützung noch im Beta-Stadium 
befindet - mit anderen Worten, sie kann Fehler aufweisen und Schwierigkeiten in der 
Anwendung  bereiten. Außerdem muss man davon ausgehen, dass die Thread-
Unterstützung in zukünftigen Versionen von Perl noch etliche Änderungen erfahren 
wird. Informieren Sie sich auf alle Fälle in der POD-Dokumentation, die bei dem 
Thread-Modul dabei ist.
Eine zweite bedeutsame Änderung ist die Integration eines Perl-Compilers. Der Compiler, mit Namen perlcc, kann ein Perl-Modul in eine native Bibliothek konvertieren/kompilieren oder ein Perl-Skript in C-Code konvertieren und diesen Code in eine ausführbare Datei kompilieren. Genau genommen ist perlcc das Front- End zu einer generischen Kompilierendstufe in Perl (die Module B und O), mit der Sie Perl-Skripts in quasi alles konvertieren oder kompilieren können.
  Perl 5.005 enthält außerdem eine neue Maschine für reguläre Ausdrücke, die 
selbsttätig etliche Fehler behebt und einige Neuheiten aufweist. Um die Performance 
zu verbessern, können Sie reguläre Ausdrücke außerdem mit dem neuen C-Operator 
vorkompilieren. Weitere Informationen hierzu finden Sie in den Manpages perlre und 
perlop.
  Da dieses ganze Kapitel ein einzig großer Vertiefungsabschnitt ist, gibt es eigentlich 
nicht allzuviel in diesem Abschnitt zu sagen. Deshalb möchte ich Sie an dieser Stelle 
noch einmal auf folgendes aufmerksam machen: Wenn Sie Probleme, Fragen oder 
Schwierigkeiten haben oder einfach nur wissen wollen, wie sich ein bestimmter Perl-
Teil verhält - von den elementaren Operatoren über die regulären Ausdrücken und 
die Referenzen bis zu den Modulen -, sollten Sie neben der Perl-Dokumentation 
(Manpages und POD-Dateien) auf alle Fälle die häufig gestellten Fragen (FAQs) zu Perl 
zu Rate ziehen. Das Kamelbuch (Programmieren mit Perl, das ich am Tag 1 im 
Vertiefungsabschnitt erwähnt habe) kann Ihnen helfen zu verstehen, wie sich Perl in 
verschiedenen Situationen verhält. Und wenn Sie trotzdem immer noch festhängen, 
nutzen Sie das Web - www.perl.com, www.activestate.com (für Windows) und viele 
der anderen Websites, die ich im Laufe dieses Buches erwähnt habe, können Ihnen 
dabei behilflich sein. Schließlich gibt es noch eine Reihe von Newsgroups (wie die 
comp.perl-Hierarchie - insbesondere comp.perl.misc) und Mailing-Listen, über die 
Sie andere Perl-Programmierer kontaktieren können.
Heute ist der Tag, an dem wir alle losen Enden zusammenbinden. So haben wir heute eine Reihe von zusätzlichen Perl-Elementen betrachtet, die ich aus Zeit- und Platzgründen in keinem der anderen 19 Kapiteln unterbringen konnte. Dieses Mischmasch umfaßt:
eval
   
 Meinen Glückwunsch! Jetzt bleibt uns nur noch ein Tag, und der ist ganz den Beispielen gewidmet. Sie haben Perl in ausreichendem Umfang kennengelernt, um einige aufregende Dinge zu machen. Also nur zu! Und vergessen Sie nicht - Perl ist ein Gemeinschaftsprodukt. Nutzen Sie die Module im CPAN. Und sollten Sie selbst etwas schreiben, von dem Sie meinen, dass auch andere es gebrauchen könnten, stellen Sie es doch auch in das CPAN.
Frage:
 	 	 	 	 	 	 	 	 	 	 	 Meine Einzeiler funktionieren nicht in MacPerl.
Antwort:
 Stellen Sie im Dialog Edit->Preferences->Scripts sicher, dass Sie die Option 
Run Scripts Opened from Finder markiert haben. Wenn Sie hier Edit 
ausgewählt haben, lassen sich Ihre Einzeiler nicht ausführen.
Frage:
 Meine Einzeiler funktionieren nicht unter Windows.
Antwort:
 Es gibt Unterschiede zwischen den Anführungszeichen in der DOS/Windows-
Befehlszeile und in Unix. Unter Unix können Sie einfache und doppelte 
Anführungszeichen verwenden, unter Windows nur doppelte. Deshalb sollten 
Sie sich vergewissern, dass Ihre Einzeiler unter Windows vorn und hinten in 
doppelten Anführungszeichen stehen und alle Anführungszeichen im Skript 
selbst mit einem Backslash markiert sind.
Frage:
 Meine Einzeiler funktionieren nicht in Unix.
Antwort:
 Sie funktionieren nicht? Haben Sie das Skript auch wirklich in eine Zeile 
eingegeben, ohne Return-Zeichen? Haben Sie auch nicht vergessen, das 
gesamte Skript in einfache Anführungszeichen zu setzen? Haben Sie an die 
Perl-Option -e gedacht? Wenn Sie alle diese Punkte überprüft haben, stellen 
Sie sicher, dass Sie das gleiche Skript ausführen können, wenn Sie es in einer 
Datei abspeichern.
Frage:
 Aus Ihrer Beschreibung entnehme ich, dass Perl die OOP-Konzepte der 
öffentlichen (public) und privaten (private) Daten nicht unterstützt. Was sollte dann 
jemand daran hindern, Methoden zu verwenden, die nicht als Teil der öffentlichen 
API ihrer Klasse gedacht sind?
Antwort:
 Nichts. Das objektorientierte Modell von Perl unterscheidet nicht zwischen 
privater und öffentlicher API. Es geht davon aus, dass Sie und die 
Programmierer, die Ihre Klassen verwenden, sich anständig verhalten, was die 
API angeht. Als Entwickler einer Klasse sollten Sie Ihre API dokumentieren 
und angeben, welche Ihrer Methoden öffentlich sind (dazu eignet sich POD 
sehr gut), und dann davon ausgehen, dass alle, die Ihre Klasse verwenden, 
sich auch an diese Vorgaben halten. Umgekehrt sollten auch Sie, wenn Sie die 
Klassen anderer Programmierer verwenden, sich an deren dokumentierte 
öffentliche API halten und interne Methoden oder Daten nur verwenden, 
wenn Sie genau wissen, was Sie tun (und das Risiko zu tragen bereit sind).
Frage:
 	 	 	 	 	 	 	 Mehrfachvererbung ist sehr verwirrend und fehleranfällig. Warum hat sich Perl 
nicht auf die einfache Vererbung beschränkt?
Antwort:
 Um damit die Mächtigkeit der Sprache zu beschränken? Es sollte Ihnen an 
dieser Stelle im Buch bereits aufgefallen sein, dass Perl zu keiner Zeit wirklich 
versucht, den Programmierer in seiner Arbeit Grenzen zu setzen. 
Mehrfachvererbung mag zwar oft verwirrend und auch schwierig zu debuggen 
sein, aber sie ist auch unglaublich leistungsstark, wenn Sie zusammen mit 
einem guten Design verwendet wird (und vergessen Sie nicht, ein gutes 
Design bedingt nicht unbedingt Vererbung). Die Entwickler von Perl lassen 
Ihnen lieber genug Seil, um sich aufzuhängen, als dass sie Sie zu knapp 
halten, so dass Sie letztlich nicht genug Seil haben, um einen Knoten zu 
binden.
Frage:
 Wo, zum Teufel, kommen die Begriffe I18N und L10N her?
Antwort:
 Es stehen jeweils 18  Buchstaben zwischen dem I und dem N in dem Wort 
»Internationalization« (Internationalisierung) und 10 Buchstaben zwischen 
dem L und dem N in »Localization« (Lokalisierung). Internationalization und 
Localization sind wirklich sehr lange Wörter. Programmierer mögen das 
nicht.
Frage:
 Ihre Beschreibung der Perl-Extensionen erläutert, wie man C-Code aus einem 
Perl-Skript heraus aufruft. Wie ruft man Perl-Code von einem C-Programm aus 
auf?
Antwort:
 Schlagen Sie in der perlcall-Manpage nach. Außerdem müssen Sie sich in der 
XS-Sprache auskennen und wissen, wie man Erweiterungen konstruiert.
Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, und Übungen, die Sie anregen sollen, das eben Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Versuchen Sie, das Quiz und die Übungen zu beantworten und zu verstehen, bevor Sie zur Lektion des nächsten Tages übergehen.
-e
-i
-p
eval? Wozu verwendet man sie?
 perl -p 's/t/T/q';
perl -ne 'print 'Zeile: ', reverse $_;';
EinfacheKlasse, die drei Instanzvariablen 
enthält: a, b und c. Nehmen Sie folgende Methoden mit auf:
new-Konstruktor, um die Variablen a, b und c zu erzeugen und zu 
initialisieren.
   
 a, b und c auszugeben und zu ändern. 
Implementieren Sie diese, wie Sie wollen.
   
 a, b und c auszugeben. Vergewissern Sie 
sich, dass a, b und c Zahlen enthalten; geben Sie andernfalls Fehlermeldungen 
aus.
   
Hier die Antworten auf die Workshop-Fragen aus dem vorigen Abschnitt.
-e führt ein Perl-Skript (einen Einzeiler) von der Befehlszeile aus.
 -i bearbeitet Dateien. Das bedeutet, das Ergebnis des Skripts wird in 
der Originaldatei gespeichert. Wird der Option -i eine Dateiextension als 
Argument mitgegeben, wird diese verwendet, um eine Sicherungsdatei der 
Originalversion der Datei zu erstellen.
 -p bettet den Perl-Einzeiler in eine while-Schleife (<>) mit einer print-
Anweisung am Ende ein. Wenn Sie die Zeilen einer Datei einzeln bearbeiten und 
dann ausgeben wollen, sollten Sie diese Option verwenden, um sich Tipparbeit zu 
ersparen.
 methode $obj,1,2,3;
$obj->methode(1,2,3);
format eine Formatschablone definieren und das Ergebnis mit write ausgeben.
 troff konvertiert werden kann.
 eval wird verwendet, um Perl-Codefragmente en passant während 
der Ausführung eines Skripts auszuwerten. Sie können eval dazu nutzen, um 
andere Skripts in Ihr aktuelles Skript aufzunehmen oder Codeabschnitte zu testen, 
bevor Sie sie richtig ausführen lassen.
 -T. Der Modus wird allerdings auch automatisch eingeschaltet, wenn 
sich die Benutzer- oder Gruppen-ID des Skripts von der Benutzer- oder Gruppen-
ID der Person unterscheidet, die das Skript ausführt (ist beispielsweise für CGI-
Skripts, die auf einem Webserver ausgeführt werden, der Fall).
 fork zu bewerkstelligen. Aber mit der Verwendung von fork waren Ihre Skripts 
nicht mehr auf andere Plattformen portierbar. Durch Threads wurde das Problem 
jetzt gelöst.
    perl -e ' while (<>){while (/t/g){$c++;}};print $c;' datei.txt
     perl -e 'while(<>){$sum+=$_;}print "$sum\n";'
 perl -pe -i.bak 's/ /\t/g' ozy.txt
-e fehlt.
 reverse. Dieser Einzeiler erweckt den 
Eindruck, dass die einzelnen Eingabezeilen zeichenweise in umgekehrter 
Reihenfolge mit dem Wort »Zeile« am Anfang ausgegeben werden. Sie sollten sich 
jedoch in Erinnerung rufen, dass die reverse-Funktion je nach Kontext (Skalar- 
oder Listenkontext) ein unterschiedliches Verhalten aufweist. In diesem Falle wird 
reverse in einem Listenkontext aufgerufen, da die Argumente zu print immer 
eine Liste oder eine Kombination von Listen sind. Doch damit wird nur die 
Reihenfolge der Zeilen in einem Array umgedreht. Das Argument $_ wird dann in 
eine Liste konvertiert, diese Liste mit einer Zeile umgedreht und anschließend 
ausgegeben. Mit anderen Worten, äußerlich passiert nichts.
 reverse-Funktion in 
einem skalaren Kontext aufrufen. Dieser Fehler kann schnell mit der scalar-
Funktion behoben werden:
perl -ne 'print 'Zeile: ', scalar (reverse $_);'
reverse umzudrehen und ihn dann mit dem frisch angehängten Neue-Zeile-
Zeichen wieder auszugeben:
perl -ne 'chomp;print "Zeile: ", scalar(reverse $_), "\n" ; '
-l. Damit wird das Neue-Zeile-Zeichen von der Eingabe entfernt, um 
es (oder irgendein anderes Zeilenende-Zeichen Ihrer Wahl) hinterher für Sie 
wieder anzuhängen:
perl -lne 'print "Zeile: ", scalar(reverse $_);'
a, b oder c heißt).
#!/usr/bin/perl -w
package EinfacheKlasse;
sub new {
my ($classname, $a, $b, $c) = @_;
my $self = {};
$self->{a} = $a;
$self->{b} = $b;
$self->{c} = $c;
return bless $self, $classname;
}
# der längste Weg
sub getA {
my $self = shift;
return $self->{a};
}
sub setA {
my $self = shift;
if (@_) {
$self->{a} = shift;
} else {
warn "kein Argument; verwende undef\n";
$self->{a} = undef;
}
}
# ein etwas allgemeinerer Weg, der mehr Argumente benötigt.
sub get {
my ($self, $var) = @_;
if (!defined $var) {
print "Keine Variable!\n";
return undef;
} elsif (!defined $self->{$var}) {
print "Variable nicht definiert oder ohne Wert.\n";
return undef;
} else {
return $self->{$var};
}
}
sub set {
my ($self, $var, $val) = @_;
if (!defined $var or !defined $val) {
print "Brauche Variable und Wert als Argument!";
return undef;
} else {
$self->{$var} = $val;
return $val;
}
}
# ein wirklich allgemeiner Weg
sub AUTOLOAD {
my $self = shift;
my $var = $AUTOLOAD;
$var =~ s/.*:://;
$var =~ s/[gs]et//;
$var = lc $var;
if (@_) {
$self->{$var} = shift;
return $self->{$var};
} else {
return $self->{$var};
}
}
sub sum {
my $self = shift;
my $sum = 0;
foreach ('a','b','c') {
if (!defined $self->{$_} or $self->{$_} !~ /^\d+/ ) {
warn "Variable $_ enthaelt keine Zahl.\n";
} else { $sum += $self->{$_}; }
}
return $sum;
}
package main;
$obj = new EinfacheKlasse (10,20,30);
print "A: ", $obj->getA(), "\n";
$obj->setA("foo");
print "A: ", $obj->getA(), "\n";
print "B: ", $obj->get('b'), "\n";
$obj->set('b', 'bar');
print "B: ", $obj->get('b'), "\n";
# es gibt keine getC-Methode; autoload
print "C: ", $obj->getC(), "\n";
$obj->setC('baz'); # ditto setC
print "C: ", $obj->getC(), "\n";
# zurücksetzen
print "\nA: 10\n";
$obj = new EinfacheKlasse (10);
print "Summe: ", $obj->sum(), "\n";
print "\nA: 10 B: 5\n";
$obj = new EinfacheKlasse (10,5);
print "Summe: ", $obj->sum(), "\n";
print "\nA: 10 B: 5 C: 5\n";
$obj = new EinfacheKlasse (10,5,5);
print "Summe: ", $obj->sum(), "\n";




