Perl
Tutorial
Dies ist eine
Bearbeitung des Perl Tutorials von Nik Silver ( School of Computer Studies,
University of Leeds GB). Das Ziel dieses Tutorials ist es, die Grundlagen
von Perl zu erarbeiten, um effizient CGI-Scripts zu schreiben. Dabei geht
es nicht darum, die Programmiersprache Perl erschöpfend zu behandeln,
sondern um den Einstieg in weitere eigene Bemühungen zu schaffen.
Diese HTML-Version ist als tar.gz - File verfügbar.
Daneben gibt
es für Perl V5 die Manpages in HTML-Format. oder ebenfalls tar.gz
- File.
Musterlösungen!
Es kann schon mal vorkommen, dass dieser Link ins Leere zeigt. Dann gibt's
nur eines: später probieren!
Die folgende
Themen werden in diesem Tutorial behandelt:
-
Das erste Perl
Programm
-
Die erste Zeile
-
Kommentare und
Anweisungen
-
Einfache Ausgabe
-
Ein Programm ausführen
-
Skalare Variablen
-
Operationen und
Zuweisungen
-
Interpolation
-
Uebung
-
Array Variablen
-
Array Zuweisungen
-
Arrays ausgeben
-
Uebung
-
Assoziative Arrays
-
Operatoren
-
Umgebungs-Variablen
-
Files
-
Kontrollstrukturen
-
foreach
-
Bool'sche Operationen
-
for
-
while und until
-
Uebung
-
Bedingungen
-
Mustererkennung
-
Reguläre Ausdrücke
(RA)
-
Die Defaultvariable
$_
-
Mehr über
RA's
-
Ein paar Beispiele
-
Uebung
-
Ersetzen, Uebersetzen
von Strings
-
Optionen
-
Muster wiederverwenden
-
Uebersetzen
-
Uebung
-
Mehr String-Funktionen
-
Binäre Daten
und Files
-
Binäre Daten
-
Formattierte Ausgabe
-
Uebung
-
Subroutinen
-
Parameter
-
Rückgabewerte
-
Lokale Variablen
mit my
-
Lokale Variablen
mit local
-
Uebung
-
'Typeglobs'
und
Referenzen
-
Typeglobs
-
Referenzen
-
Uebung
-
Module
-
Packages
-
Klassen
-
Module
-
Uebung 1
-
Uebung 2
-
Einführung
in Perl 5 Objekte
Das erste Programm
Hier ist das
erste Programm um uns anzuwärmen.
#!/usr/local/bin/perl
#
# Das unvermeidliche erste Programm
#
print 'Hello world.'; # Ausgabe eines Textes
Im folgenden werden
wir jeden Teil dieses Programmes besprechen.
Die erste Zeile
Jedes Perl Programm
beginnt mit einer solchen Zeile,
#!/usr/local/bin/perl
obschon sie von
System zu System unterschiedlich aussehen kann. Diese Zeile sagt dem Computer,
was er bei der Ausführung zu tun hat. (In diesem Fall soll er es durch
den Perl-Interpreter schicken.)
Kommentare und
Anweisungen
Das # Symbol
eröffnet einen Kommentar. Alles zwischen # und dem Zeilenende
wird vom Interpreter ignoriert (Ausnahme: erste Zeile). Kommentare können
überall im Programm verwendet werden. Der einzige Weg um Kommentare
über mehrere Zeilen ausdehnen zu können, ist die Verwendung von
#
in jeder Zeile.
Alles übrige
sind Perl-Anweisungen, welche mit einem Strichpunkt beendet werden müssen,
wie die letzte Zeile oben.
Einfache Ausgabe
Die print Funktion
gibt Information aus. Im obigen Fall gibt sie den String Hello world.
aus. Und selbstverständlich endet die Anweisung mit einem Strichpunkt.
Sie werden feststellen,
das obiges Programm ein nicht ganz erwartetes Resultat erzeugt. Wir werden
es deshalb als nächstes laufen lassen.
Ein Programm ausführen
Schreibe das
Beispielprogramm mit einem Texteditor und speichere es ab. (Emacs hat einen
Perl-Modus 'M-x perl-mode'!)
Danach muss
es ausführbar gemacht werden mit
chmod u+x progname
als UNIX-Kommandozeile,
wobei progname der Name Programmfiles ist. Um das Programm zu starten,
muss eine der folgenden Zeilen eingegeben werden: .
perl progname
./progname
progname
Vielleicht haben
Sie Glück und das Programm wird ausgeführt. Möglicherweise
erscheinen aber Fehlermeldungen, oder es geschieht überhaupt nichts.
Man kann mit folgendem Befehl perl veranlassen, Warnungen und weitere hilfreiche
Meldungen auszugeben, bevor das Programm ausgeführt wird:
perl -w progname
Perl hat auch einen
Debugger. Er wird mit
perl -d progname
gestartet. Bei
der Ausführung eines Perl-Programmes (Perl-Script) wird der Text zuerst
'kompiliert' (interpretiert). Dieser Schritt erzeugt auch die Fehlermeldungen.
Anschliessend wird es ausgeführt. Die eigentliche Laufzeit ist vergleichbar
mit einem C-Programm. Je nach Länge des Programmes, muss mit einer
gewissen 'Kompilierzeit' gerechnet werden, welche nur mit speziellen Hilfsmitteln
(undump) ausgeschaltet werden kann.
Bevor wir weitermachen,
sollte das Programm laufen. Der Output entspricht vielleicht nicht ganz
den Erwartungen, mindestens ist er nicht so schön. Zunächst wenden
wir uns den Variablen zu und danach können wir auch die Ausgaben verbessern.
Skalare Variablen
Die elementarsten
Variablen in Perl sind die skalaren Variablen. Skalare Variablen
können Zahlen und Strings beinhalten und, je nach Kontext, werden
sie als Zahlen oder Strings interpretiert. Vor dem eigentlichen Namen muss
immer ein $ -Zeichen stehen. Im folgenden Beispiel
$priority = 9;
wird der Variablen
$priority den Wert 9 zugeordnet, es ist aber auch möglich der genau
gleichen Variablen einen String zuzuordnen:
$priority = 'high';
Perl akzeptiert
auch Zahlen als Strings:
$priority = '9';
$default = '0009';
Damit können
problemlos auch arithmetische Operationen ausgeführt werden.
Variablennamen
können aus Buchstaben, Zahlen und Unterstrich zusammengesetzt werden.
Sie sollten jedoch nicht mit einer Zahl beginnen und die Variable $_
hat eine spezielle Bedeutung. Perl unterscheidet zwischen Gross- und Kleinschreibung,
dh. $a und $A sind verschieden.
Operationen
und Zuweisungen
Perl verwendet
alle gebräuchlichen C-Operatoren.
$a = 1 + 2; # Addiere 1 und 2 und speichere Resultat in $a
$a = 3 - 4; # Subtrahiere 4 von 3 ...
$a = 5 * 6; # Multipiziere 5 und 6
$a = 7 / 8; # Dividiere 7 mit 8 ($a = 0.875)
$a = 9 ** 10; # Neun hoch zehn
$a = 5 % 2; # % MOD 2
++$a; # Inkrement $a, Rückgabe von $a
$a++; # Rückgabe von $a, Inkrement $a
--$a; # Dekrement $a, Rückgabe von $a
$a--; # Rückgabevon $a, Dekrement $a
Für Strings
gibt es unter anderem:
$a = $b . $c; # Konkateniere $b und $c
$a = $b x $c; # Füge $b $c-mal zusammen
Zuweisungen:
$a = $b; # $a wird $b
$a += $b; # $a wird um $b vergrössert
$a -= $b; # $a wird um $b verkleinert
$a .= $b; # $a wird mit $b konkateniert
Bei der Zuweisung
$a
= $b macht Perl eine Kopie von $b und weist diese $a zu. Eine darauffolgende
Aenderung von $b ändert $a nicht.
Weitere Operatoren
sind im Manual beschrieben. Zugang zum Manual erhält man auch mit
man
perlop.
Substitution
Folgende Programmzeilen
sollen apples and pears ausgeben. Wir wollen den Operator für
Konkatenation verwenden:
$a = 'apples';
$b = 'pears';
print $a.' and '.$b;
Es wäre schöner,
nur einen String im print statement zu verwenden, aber mit
print '$a and $b';
erhalten wir genau
$a
and $b, was nicht unserem Wunsch entspricht. Die Verwendung von doppelten
Anführungszeichen veranlasst Perl die Variablen aufzulösen (engl.
interpolation):
print "$a and $b";
Daneben werden
auch Spezialzeichen, wie \n und \t aufgelöst. \n
ist ein Zeilenumbruch und \t ist ein Tabulator.
Uebung
Wir schreiben das
Hello-World-Programm um, sodass (a) der String einer Variablen zugeordnet
wird und (b) diese Variable mit anschliessendem Zeilenumbruch ausgegeben
wird. Wir benützen doppelte Anführungszeichen und nicht den Operator
für Konkatenation.
Array
Variablen
Eine weitere
Art von Variablen sind die Array Variablen. Sie stellen eine Liste
von skalaren Variablen dar (ie. Zahlen und Strings). Die Namen von Array-Variablen
haben dasselbe Format, wie die skalaren Variablen, ausser das sie anstelle
eines $-Symbols, am Anfang ein @-Symbol brauchen. Beispiel:
@food = ('apples', 'pears', 'eels');
@music = ('whistle', 'flute');
Damit werden der
Variablen @food eine Liste von drei Elementen, der Liste @music eine Liste
von zwei Elementen zugewiesen.
Die Array-Elemente
werden mittels Indizes in eckigen Klammern zugegriffen. Der Index beginnt
bei 0. Der Wert von
$food[2]
ist somit eels.
Beachte, dass nicht mehr @, sondern $ am Anfang des Variablennamens
steht. Ein Element eines Arrays ist ein Skalar!
Array
Zuweisung
Wie alles in Perl
kann der gleiche Ausdruck in unterschiedlichem Kontext ein anderes Resultat
erzeugen. Die erste Zuweisung unten ergänzt den Array @music. Somit
sind beide Zuweisungen äquivalent.
@moremusic = ('organ', @music, 'harp');
@moremusic = ('organ', 'whistle', 'flute', 'harp');
Damit können
Elemente zu einem Array hinzugefügt werden. Ein anderer Weg um Elemente
hinzuzufügen sieht folgendermassen aus:
push(@food, 'eggs');
Damit wird das
Element eggs ans Ende des Arrays @food angehängt. Man kann
auch mehrere Elemente auf's Mal anhängen:
push(@food, 'eggs', 'lard');
push(@food, ('eggs', 'lard'));
push(@food, @morefood);
Die push-Funktion
hat als Rückgabewert die neue Länge des Arrays.
Analog kann
mit pop das letzte Element von einer Liste entfernt werden. pop
entfernt von der ursprünglichen Liste @food das letzte Element eels.
Der Rückgabewert ist das entfernte Element. @food hat nun noch zwei
Elemente:
$grub = pop(@food); # Jetzt ist $grub = 'eels' (grub=Frass)
Es ist auch möglich,
einem Array eine skalare Variable zuzuordnen. Wie immer ist der Kontext
wichtig. Die Zeile
$f = @food;
weist $f die Länge
des Arrays $food zu. Hingegen wird mit
$f = "@food";
die Liste in einen
String konvertiert, welcher zwischen den Elementen je ein Leerzeichen hat.
Mit der Spezialvariablen $" kann das Leerzeichen durch einen beliebigen
anderen String ersetzt werden. Diese Variable ist eine von vielen Spezialvariablen,
mit welchen das Verhalten von Perl gesteuert werden kann.
Arrays können
auch verwendet werden, um gleichzeitig mehrere Zuordnungen von skalaren
Variablen zu machen:
($a, $b) = ($c, $d); # Aequvalent $a=$c; $b=$d;
($a, $b) = @food; # $a und $b sind die ersten
# beiden Elemente von @food.
($a, @somefood) = @food; # $a ist das erste El. von @food
# @somefood sind die übrigen
(@somefood, $a) = @food; # @somefood ist @food und
# $a ist nicht definiert.
Zur letzten Zuweisung
ist zu bemerken, dass Arrays alle Elemente, welche sie antreffen, kopieren
werden. Damit ist diese letzte Form nicht sehr nützlich.
Zum Schluss
möchten wir noch die Länge eines Arrays bestimmen können.
Der Ausdruck
$#food
ergibt den Index
des letzten Elementes eines Arrays. Sofern wir mit dem Index 0 begonnen
haben (Achtung: Spezialvariable $[) wird die Länge von @food:
$len=$#food+1;
oder im allgemeinen:
$len=$#food+1-$[;
Arrays ausgeben
Weil der Kontext
wichtig ist, ist es nicht erstaunlich, dass die folgenden Ausdrücke
alle unterschiedliche Resultate erzeugen:
print @food; #
print "@food"; # mit doppelten Anführungszeichen
print @food.""; # in skalarem Kontext (. Konkat.)
Uebung
Wir probieren die
obigen print-Statements aus und schauen, was dabei herauskommt. Man darf
es sich auch vorher überlegen!
Hashes (Assoziative Arrays)
Normale Arrays
oder Listen erlauben den Zugriff zu den Elementen über die Elementnummern.
Das erste Element des Arrays @food ist $food[0]. Das zweite Element ist
$food[1], und so weiter. Mit Perl können aber auch Arrays erzeugt
werden, deren Elemente durch Strings referenziert werden. Diese Arrays
nennt man assoziative Arrays oder hashes (die keyword - value
-Paare werden in Hash-Tabellen abgelegt.)
Um einen Hash
zu definieren verwenden wir die normale Klammer-Notation. Der Arrayname
hat jedoch ein vorangestelles %-Zeichen (im Gegensatz zum @-Zeichen des
gewöhnlichen Arrays). Wir wollen einen Hash definieren, welcher den
Namen und das Alter von Personen enthält. Das sieht folgendermassen
aus:
%ages = ('Michael Caine', 39,
'Dirty Den', 34,
'Angie', 27,
'Willy', '21 in dog years',
'The Queen Mother', 108);
Beachte: In Perl
V5 können die Kommas durch => -Operator ersetzt werden. Damit wird
die Zusammengehörigkeit der Schlüssel-Wert-Paare dokumentiert
und er bewirkt, dass der Wert links des Operators als String interpretiert
wird. Obiges kann deshalb auch folgendermassen geschrieben werden:
%ages = ('Michael Caine' => 39,
'Dirty Den' => 34,
Angie => 27,
Willy => '21 in dog years',
'The Queen Mother', 108);
Das Alter der Leute
kann mit den folgenden Anweisungen gefunden werden:
$ages{'Michael Caine'}; # Ergibt 39
$ages{'Dirty Den'}; # Ergibt 34
$ages{Angie}; # Ergibt 27
$ages{Willy}; # Ergibt "21 in dog years"
$ages{'The Queen Mother'}; # Ergibt 108
Und mit
$ages{'ich'} = 'jung';
kann man beliebige
weitere Elemente hinzufügen.
Das %-Zeichen
wird wiederum durch ein $-Zeichen ersetzt, falls ein einzelnes Element
gemeint ist. Ein Element ist ein Skalar! Im Unterschied zu den normalen
Arrays, wo der Index in eckigen Klammern geschrieben wird, verwenden wir
bei den Hashes die geschweiften Klammern. Der Index ist ein String, eben
der Name der Person.
Ein Hash kann
in einen normalen Array umgewandelt werden, indem er einfach einem normalen
Array zugewiesen wird. Umgekehrt wird ein normaler Array in einen Hash
umgewandelt. Idealerweise hat der normale Array eine gerade Anzahl Elemente:
@info = %ages; # @info ist ein normaler Array.
# Er hat jetzt 10 Elemente.
$info[5]; # Das 5. Element von @info
# den Wert 27
%moreages = @info; # %moreages ist ein assoziativer
# Array. Es ist der gleiche wie %ages
Operatoren
Die Elemente von
assoziative Arrays sind ungeordnet (hash-tables) aber man kann die Elemente
der Reihe nach mit den Funktionen keys und values zugreifen:
foreach $person (keys %ages)
{
print "Ich kenne das Alter von $person.\n";
}
foreach $age (values %ages)
{
print "Jemand ist $age Jahre alt.\n";
}
Die Funktion keys
erzeugt ein Liste der Schlüsselwörter (das sind die Indizes)
des Hash. Die Funktion values erzeugt ein Liste der Werte. Die Reihenfolge
der beiden Listen ist gleich, sie hat jedoch nichts mit der Reihenfolge
der Eingabe zu tun.
In skalarem
Kontext geben die Funktionen keys und values die Anzahl key/value-Paare
im assoziativen Array an.
Daneben gibt
es noch eine Funktion each, welche einen Array mit zwei Elementen erzeugt,
dem Schlüsselwort und dem Wert. Aufeinanderfolgende Aufrufe von each
geben immer ein neues key/value-Paar aus, solange solche vorhanden sind:
while (($person, $age) = each(%ages))
{
print "$person ist $age Jahre alt\n";
}
Umgebungs-Variablen
UNIX kennt das
Konzept von Umgebungsvariablen, welche es erlauben, Informationen über
das System interessierten Programmen weiterzugeben. Zum Beispiel wird in
der USER-Variablen den Namen des eingeloggten Benutzers gespeichert und
in der HOME-Variablen dessen Home-Directory, usf. Perl stellt diese Variablen
in dem assoziativen Array %ENV zur Verfügung. Die Schlüsselwörter
dieses Arrays sind die Namen der Umgebungsvariablen. Somit wird das folgende
Programmstück die aktuellen Werte der Umgebungsvariablen USER und
HOME ausgeben:
print "Du bist User $ENV{'USER'} mit ";
print "Homedirectory $ENV{'HOME'}\n";
Files
Das folgende
Perlprogramm liest ein File und gibt den Inhalt des Files aus.
#!/usr/local/bin/perl
#
# Program to open the password file, read it in,
# print it, and close it again.
$file = '/etc/passwd'; # Filename zuweisen
open(INFO, $file); # File öffnen
@lines = <INFO>; # in Array einlesen
close(INFO); # File schliessen
print @lines; # Array ausgeben
Die Funktion open
öffnet ein File zum lesen. Der erste Parameter ist ein Filehandle,
welcher es erlaubt, das File in Zukunft zu referenzieren. Der zweite Parameter
ist ein Ausdruck, der den Filenamen bezeichnet.
Die Funktion
close schliesst das File.
Selbstverständlich
möchten wir nicht nur Files lesen, sondern auch schreiben oder etwas
zu einem File hinzufügen können. Die Verwendung des richtigen
Prefix zum Filenamen der Funktion open erlaubt diese Dinge:
open(INFO, $file); # Lesen
open(INFO, ">$file"); # Schreiben
open(INFO, ">>$file"); # Anhängen
open(INFO, "<$file"); # Lesen
Um etwas in ein
geöffnetes File zu schreiben, verwenden wir die Funktion print
mit einem zusätzlichen Parameter, dem Filehandle:
print INFO "This line goes to the file.\n";
Dieser Ausdruck
schreibt in File mit Filehandle INFO obiger Text zwischen Hochkommas. Beachte:
Es darf kein Komma nach INFO stehen! Zwecks besserer Lesbarkeit werden
Filehandles mit Grossbuchstaben bezeichnet.
Im obigen Programm
wird ein File eingelesen. Der Filehandle ist INFO und um es einzulesen
verwendet man spitze Klammern. Der Ausdruck
@lines = <INFO>;
liest das File
in den Array @lines. Beachte, dass das gesamte File auf's Mal eingelesen
wird. Der Grund liegt im Array-Kontext. Falls @lines durch die skalare
Variable $line ersetzt würde, würde nur eine Zeile eingelesen
und beim nächsten Aufruf die nächste. $line speichert die ganze
Zeile inklusive newline-character.
Die Filehandles
STDIN, STDOUT und STDERR sind vordefiniert. Defaultmässig schreibt
print
auf STDOUT und <> liest von STDIN ( <> ist äquivalent
zu <STDIN>).
Uebung
Wir ändern
das obige Programm, sodass das ganze File mit einem # Symbol am Anfang
jeder Zeile ausgegeben wird. Dazu sollte nur eine Zeile zum Programm hinzugefügt
und eine weitere geändert werden müssen. Wir verwenden dazu die
Spezialvariable $". Mit Files können unvorhergesehene Dinge geschehen,
deshalb ist es nützlich, die -w-Option zu verwenden, welche
wir im Abschnitt Ein Programm ausführen erwähnt haben.
Kontrollstrukturen
Weitere interessante
Möglichkeiten werden mit Kontrollstrukturen und Schleifen eröffnet.
Perl unterstützt viele verschiedene Arten von Kontrollstrukturen,
welche zum Teil C ähnlich sehen, aber auch an Pascal erinnern. Wir
werden hier ein paar davon ansehen.
foreach
Um jedes Element
eines Arrays oder einer andern Listenstruktur (wie zun Beispiel die Zeilen
eines Files) zu durchlaufen, kann foreach verwendet werden. Das sieht folgendermassen
aus:
foreach $morsel (@food) # Gehe der Reihe nach durch
# @food und nenne das
# Element $morsel
{
print "$morsel\n"; # Ausgabe des Elementes
print "Yum yum\n"; # That was nice
}
Die Anweisungen,
welche jedesmal durchgeführt werden sollen, müssen in geschweiften
Klammern angegeben werden. Falls @food leer wäre, würde der Block
in geschweiften Klammern nie durchlaufen.
Bool'sche
Operatoren
Die nächsten
Anweisungen testen die Gleichheit zweier Ausdrücke. In Perl wird jede
Zahl ungleich Null und jeder nicht leere String als true betrachtet. Die
Zahl Null, Null als String und der leere String sind false. Hier sind ein
paar Tests auf Gleichheit für Zahlen und Strings:
$a == $b # $a numerisch gleich $b?
# Achtung: Nicht = verwenden
$a != $b # $a numerically ungleich $b?
$a eq $b # $a gleicher String wie $b?
$a ne $b # $a und $b nicht der gleiche String?
Es gibt auch die
logischen AND, OR und NOT:
($a && $b) # ist $a und $b true?
($a || $b) # ist entweder $a oder $b true?
!($a) # ist $a false?
for
Die for-Struktur
von Perl ist vergleichbar mit C:
for (init; test; inkr)
{
first_action;
second_action;
etc
}
Zuerst wird init
ausgeführt. Falls test true ist, wird der Block von Anweisungen
in geschweiften Klammern ausgeführt. Nach jedem Durchgang wird inkr
ausgeführt. Mit der folgenden for-Schleife werden die Zahlen
1 bis 9 ausgegeben:
for ($i = 0; $i < 10; ++$i) # Starte mit $i = 1
# falls $i < 10
# Inkr. $i vor Block
{
print "$i\n";
}
Die reservierten
Wörter for und foreach können für beide Strukturen verwendet
werden. Perl merkt dann schon, was gemeint ist!
while
und until
Das folgende Programm
liest eine Eingabe von Keyboard und wiederholt die Anfrage, bis das korrekte
Passwort eingegeben wurde.
#!/usr/local/bin/perl
print "Password? "; # Fragt nach Input
$a = <STDIN>; # liest input
chop $a; # löscht \n am Ende
while ($a ne "fred") # Solange $a falsch ist
{
print "sorry. Again? "; # Fragt wieder
$a = <STDIN>; # liest
chop $a; # löscht \n am Ende
}
Die while-Schleife
sollte soweit klar sein. Wie immer haben wir einen Block von Anweisungen
in geschweiften Klammern. Ein paar Dinge können wir hier noch erwähnen:
Erstens können wir von STDIN lesen, ohne es zuerst geöffnet zu
haben. Zweitens wird mit der Eingabe des Passwortes auch ein newline-character
in $a abgespeichert. Drittens ist die chop-Function dazu da, den
letzten Buchstaben eines Strings abzuschneiden, in diesem Fall den newline-character.
Um das Gegenteil
zu testen, können wir die until-Schleife in genau gleicher
Weise verwenden. Damit wird der Block solange ausgeführt, bis
der Test true ist und nicht solange er true ist.
Eine andere
Art vorzugehen, ist die Verwendung des while- oder until-Tests
am Ende des Blocks anstatt am Anfang. Dazu benötigt man noch den do-Operator,
welcher den Blockanfang markiert. Falls wir die Meldung sorry. Again
weglassen, könnten wir das Passwortprogramm folgendermassen schreiben:
#!/usr/local/bin/perl
do
{
print "Password? "; # Fragt nach Input
$a = <STDIN>; # liest Input
chop $a; # löscht \n
}
while ($a ne "fred"); # Nochmals solange falscher Input
Uebung
Wir ändern
das Programm der letzten Uebung, indem jede Zeile einzeln eingelesen werden
soll und die Ausgabe am Anfang die Zeilennummer aufweist. Die folgende
Struktur ist vielleicht hilfreich:
while ($line = <INFO>)
{
...
}
Danach hätten
wir noch gerne die Zeilennummern im folgenden Format: 001, 002, ..., 009,
010, 011, 012., etc. Um das zu erhalten, braucht es nur einen Zusatz von
vier Buchstaben in einer Zeile. Perl ist da sehr flexibel...
Bedingungen
Natürlich
kennt Perl auch if/then/else-Anweisungen. Sie sehen wie folgt aus:
if ($a) {
print "The string is not empty\n";
} else {
print "The string is empty\n";
}
Erinnern wir uns,
das ein String als false betrachtet wird, falls er leer ist, sowie wenn
$a gleich 0 ist.
Es gibt aber
noch mehr Möglichkeiten:
if (!$a) { # Das ! ist der NOT Operator
print "The string is empty\n";
} elsif (length($a) == 1) { # falls obiges false
print "The string has one character\n";
} elsif (length($a) == 2) { # falls obiges false
print "The string has two characters\n";
} else { # andernfalls
print "The string has lots of characters\n";
}
Beachte: bei elsif
muss tatsächlich das 'e' fehlen.
Uebung
Wir nehmen ein
ziemlich langes File, welches Text und Leerzeilen enthält. Zum Beispiel
gibt es folgende Geschichte aus dem Tages-Anzeiger. Von der letzten Uebung
haben wir ein Programm, welches das Passwort-File mit Zeilennummerierung
ausgibt. Aendere dieses Programm, sodass die Zeilennummern bei Leerzeilen
nicht mitgerechnet und ausgegeben werden, jedoch die Zeile selber immer
ausgegeben wird. Beachte, dass beim Einlesen eines Files, jede Zeile am
Ende den newline-Character enthält.
Mustererkennung
Eine der nützlichsten
Eigenschaften von Perl (wenn nicht die nützlichste Eigenschaft)
ist das mächtige String-Handling. Und der Motor des String-Handling
sind die regulären Ausdrücke (RA) zur Mustererkennung, welche
auch von vielen UNIX Hilfsprogrammen verwendet werden.
Reguläre Ausdrücke
Ein regulärer
Ausdruck steht zwischen zwei Schrägstrichen '/' und der Mustererkennungs-Operator
ist =~. Der folgende Ausdruck ist true, falls der String (oder das
Muster, oder der reguläre Ausdruck) das in der Variablen $satz
vorkommt.
$satz =~ /das/;
Effektiv ist der
"generische Musteroperator" m//. Die Schrägstriche können mit
der m-Notation durch ein beliebiges anderes Zeichen ersetzt werden. .
$satz =~ m:das:;
Ohne m-Notation
braucht es die Schrägstriche. Das ist die Schreibweise, die man aus
historischen Gründen auch fast immer sieht.
Der RA unterscheidet
Gross- und Kleinschreibung, dh. mit
$satz = "Das Muster kommt vor!";
wird der obige
Vergleich false. Der Operator !~ macht das Gegenteil. Mit obiger
Zuweisung wird deshalb der Ausdruck
$satz !~ /das/
true, da der String
das
in $satz nicht auftritt.
Die Defaultvariable
$_
Wir können
die folgende Bedingung verwenden
if ($satz =~ /uster/) {
print "Das Muster \'uster\' kommt vor.\n";
}
welche eine Nachricht
ausgibt, falls wir einen der folgenden Sätze hätten:
$satz = "Ein Muster ohne Wert";
$satz = "Uster mustern";
Häufig ist
es einfacher, den Satz der Defaultvariablen $_ zuzuordnen, welche
natürlich skalar ist. Damit können wir die Verwendung der Mustererkennungs-Operatoren
umgehen und einfach schreiben:
if (/uster/) {
print "Wir sprechen von Mustern\n";
}
Die $_-Variable,
ist die Default-Variable für viele Perl-Operationen und -Funktionen
und wird sehr häufig gebraucht.
Mehr
über RAs
RA können
aber sehr viel mehr als reiner Vergleich von Zeichenketten. Es gibt viele
Spezialzeichen, die eine bestimmte Bedeutung haben. Mit diesen Spezialzeichen
wird erst die volle Funktionalität (und auch die Komplexität)
der RA's erreicht. Wir empfehlen, mit einfachen RA's zu beginnen und sich
langsam zu steigern. Die hohe Schule der RA's braucht Erfahrung und Kreativität.
Als Einstieg
schauen wir uns ein paar einfache Beispiele an. Nehmen wir an, wir hätten
einen String und möchten wissen, ob darin die Zeichenfolge ac
vorkommt. Der RA dazu ist /ac/. Anstelle von ac möchten
wir auch noch bc zulassen, dann heisst der RA /[ab]c/. Falls
nun mehrere a's und b's vor dem c erlaubt sein sollen,
können wir schreiben: /[ab]+c/. Folgende Menge von Strings
sind damit erlaubt:
ac
bc
aac
bc
abc
bac
aaac
und so weiter.
Schreiben wir anstelle des +-Zeichens ein * wäre auch
ein c alleine erlaubt. Wenn wir am Anfang sicher ein a wollen,
müssen wir /a[ab]*c/ schreiben. Welche Strings aus der obigen
Liste werden damit erkannt?
Falls die obige
Zeichenfolge am Anfang des Strings vorkommen soll, schreibt es sich so:
/^a[ab]*c/,
oder am Ende: /a[ab]*c$/.
Anstelle unserer
Zeichenfolge möchten wir Zahlen haben. Für Zahlen gibt es ein
Spezialzeichen \d, was nichts anderes bedeutet als [0123456789]
oder in Kurzform [0-9]. Diese drei Darstellungen sind äquivalent.
Nehmen wir an, wir hätten eine Nummer am Anfang unseres Strings und
anschliessend ein Leerzeichen. Der RA heisst /^\d+ /. Es könnte
aber auch sein, dass anstelle eines Leerzeichens auch ein Tabulator oder
ein Newline steht, dazu gibt es wiederum ein Spezialzeichen, das \s.
Also heisst der RA /^\d+\s/.
Verlassen wir
unser Beispiel und schauen uns weitere Spezialzeichen an:
. # Ein einzelner Buchstaben ohne newline
^ # Zeilen- oder Stringanfang
$ # Zeilen- oder Stringende
* # Null oder mehrere Male den letzten Buchstaben, greedy!
*? # ditto, aber minimal
+ # Ein oder mehrere Male den letzten Buchstaben
? # Null oder ein Mal den letzten Buchstaben
und dazu auch gleich
ein paar weitere Beispiele. Wir erinnern uns daran, das ein RA zwischen
/.../
stehen soll.
t.e # t gefolgt von einem bel. Buchstaben
# gefolgt von e
# Dieses Muster ist enthalten in
# the
# tre
# tle
# aber nicht in te
# oder tale
^f # f am Anfang einer Zeile
^ftp # ftp am Anfang einer Zeile
e$ # e am Ende einer Zeile
tle$ # tle am Ende einer Zeile
und* # un gefolgt von 0 oder mehreren d
# Dieses Muster ist enthalten in
# un
# und
# undd
# unddd (etc)
.* # Irgendein String ohne newline, weil
# . bedeutet irgendein Buchstabe ausser newline
# und * bedeutet 0 oder mehrere davon
^$ # Leerzeile
Aber das ist noch
längst nicht alles. Eckige Klammern werden verwendet um irgendein
Zeichen innerhalb zu erkennen. Wird innerhalb von eckigen Klammern ein
Bindestrich - verwendet, bedeutet das einen Zeichenbereich, ein
^
am Anfang bedeutet 'keines von diesen':
[qjk] # Entweder q oder j oder k
[^qjk] # Weder q noch j noch k
[a-z] # Irgendetwas zwischen a und z (inklusive)
[^a-z] # Keine Kleinbuchstaben
[a-zA-Z] # Irgendein Buchstabe
[a-z]+ # Irgendeine Folge von Kleinbuchstaben
Hier können
wir vielleicht vorläufig aufhören und zur Uebungsaufgabe übergehen.
Der Rest ist hauptsächlich als Referenz gedacht.
Ein senkrechter
Strich | bedeutet ein "OR" und Klammern (...) werden
verwendet, um Dinge zu gruppieren:
jelly|cream # Entweder jelly oder cream
(eg|le)gs # Entweder eggs oder legs
(da)+ # Entweder da oder dada oder dadada oder...
Und noch ein paar
Spezialzeichen mehr:
\n # Zeilenumbruch
\t # Tabulator
\w # Irgendein alphanumerischer (word) Buchstaben
# ist identisch mit [a-zA-Z0-9_]
\W # nicht alphanumerisch (non-word)
# ist identisch mit [^a-zA-Z0-9_]
\d # Eine Zahl. Ist identisch mit [0-9]
\D # Keine Zahl. Ist identisch mit [^0-9]
\s # 'whitespace character': space,
# tab, newline, etc
\S # 'non-whitespace character'
\b # Wortgrenze (nur ausserhalb [])
\B # Innerhalb eines Wortes
Zeichen, wie $,
|,
[, ), \, / sind Spezialfälle in RA's.
Falls sie als normale Zeichen verwendet werden sollen, müssen sie
mit einem 'backslash' \ markiert werden:
\| # Vertical bar
\[ # An open square bracket
\) # A closing parenthesis
\* # An asterisk
\^ # A caret symbol
\/ # A slash
\\ # A backslash
und so weiter.
Ein
paar Beispiele
Wie wir schon erwähnt
haben, ist es vermutlich das Beste, mit einfachen Beispielen zu beginnen
und langsam zu schwierigeren zu gehen. Im Perl-Programm müssen sie
wie gesagt zwischen Schrägstrichen /.../ stehen.
[01] # Enweder "0" or "1"
\/0 # Eine Division durch Null: "/0"
\/ 0 # Mit Leerzeichen: "/ 0"
\/\s0 # Mit 'whitespace':
# "/ 0" wobei das Leerzeichen auch ein Tab
# etc. sein kann0
\/ *0 # Kein oder mehrere Leerzeichen
# "/0" or "/ 0" or "/ 0" etc.
\/\s*0 # Kein oder mehrere 'whitespace'
\/\s*0\.0* # Wie vorher, aber mit Dezimalpunkt
# und möglicherweise weiteren Nullen, zB.
# "/0." und "/0.0" und "/0.00" etc und
# "/ 0." und "/ 0.0" und "/ 0.00" etc.
Uebungen
Im letzten Kapitel
zählte unser Programm alle nicht-leeren Zeilen im File roman5.txt.
Wir wollen es nun ändern, sodass es anstelle von den nicht-leeren
Zeilen, nur Zeilen mit folgenden Eigenschaften zählt:
-
dem Buchstaben
q
-
dem String Du
-
dem String Du,
welcher ein grosses oder ein kleines D haben kann
-
das Wort Du
mit oder ohne Grossbuchstaben. Verwende \b um Wortgrenzen zu erkennen.
Das Programm soll
weiterhin jede Zeile ausgeben, jedoch nur die obenerwähnten nummerieren.
Wir wollen die $_-Variable verwenden um den Mustererkennungs-Operator
=~
zu vermeiden.
Ersetzen,
Uebersetzen in Strings
Sowie Perl Muster
in Strings erkennen kann, können auch Muster durch Strings ersetzt
werden. Dazu verwenden wird die s-Funktion, welche ähnlich wie im
vi-Editor oder beim sed aussieht. Wiederum wird der Vergleichsoperator
verwendet, welcher wiederum weggelassen werden kann, falls die Ersetzung
auf der Defaultvariablen $_ gemacht werden soll.
Um den Substring
london
durch London in der Variablen $satz zu ersetzen, verwenden wir die
Anweisung
$satz =~ s/london/London/;
Mit der Defaultvariablen
$_,
sieht das folgendermassen aus
s/london/London/;
Beachte, dass die
zwei regulären Ausdrücke (london und London) insgesamt
von drei Schrägstrichen / umgeben sind. Das Resultat dieses
Ausdruckes ist die Anzahl gemachter Ersetzungen. In diesem Fall Null (false)
oder Eins (true).
Optionen
Dieses Beispiel
ersetzt nur das erste Auftreten von london im String. Verschiedene
Optionen steuern das Verhalten der s-Funktion. Falls wir alle Vorkommnisse
ersetzen wollen, müssen wir nach dem letzten Schrägstrich ein
g
anhängen.
s/london/London/g;
Wiederum ist das
Resultat dieses Ausdruckes die Anzahl gemachter Ersetzungen. In diesem
Fall Null (false) oder >Null (true).
Falls wir auch
Dinge, wie lOndon, lonDON, LoNDoN, ersetzen wollen,
könnte das ganze folgendermassen aussehen:
s/[Ll][Oo][Nn][Dd][Oo][Nn]/London/g
Ein einfacherer
Weg ist jedoch die Verwendung der i Option (i wie 'ignore case').
Der Ausdruck
s/london/London/gi;
macht eine globale
Ersetzung ohne Beachtung der Gross- oder Kleinschreibung. Die i
Option kann auch beim normalen Vergleich von Mustern /.../i
verwendet werden.
Muster
wiederverwenden
Häufig ist
es sinnvoll, die aufgefundenen Muster wiederzuverwenden. Dabei werden die
Muster in Klammern der Reihe nach in die Variablen $1,...,$9
zwischengespeichert. Diese Variablen können sowohl im gleichen regulären
Ausdruck, als auch in der Ersetzung wiederverwendet werden, indem die speziellen
Codes für reguläre Ausdrücke \1,...,\9 angewendet
werden. Das Beispiel
$_ = "Lord Whopper of Fibbing";
s/([A-Z])/:$1:/g;
print "$_\n";
ersetzt jeden Grossbuchstaben
durch denselben Buchstaben umgeben von zwei Doppelpunkten. Das heisst,
die Ausgabe lautet: :L:ord :W:hopper of :F:ibbing. Die Variablen
$1,...,$9
sind read-only Variabeln; sie können nicht direkt verändert werden.
Im folgenden
Beispiel wird die Testanweisung
if (/(\b.+\b) \1/)
{
print "Found $1 repeated\n";
}
jedes wiederholte
Wort erkennen. Der Code \b stellt eine Wortbegrenzung dar und .+
erkennt jeden nicht-leeren String. Damit erkennt \b.+\b irgendein
String zwischen Wortbegrenzern. Durch die Klammern wird eine Zwischenspeicherung
veranlasst und diese wird innerhalb des regulären Ausdrucks mit \1,
im restlichen Programm mit $1 referenziert.
Der folgende
Ausdruck vertauscht den ersten und den letzten Buchstaben einer Zeile in
der $_-Variablen:
s/^(.)(.*)(.)$/$3$2$1/
Der Code ^
erkennt den Anfang, $ das Ende einer Zeile. \1 speichert
den ersten Buchstaben; \2 speichert alles bis zum letzten Buchstaben,
welcher in \3 gespeichert wird. Danach wird die ganze Zeile ersetzt,
indem $1 und $3 vertauscht werden.
Nach einem Vergleich
hat man drei Spezial-Variabeln $`, $& und $' zur
Verfügung, in welchen die Teile vor, während und nach dem Muster
abgespeichert sind. Nach
$_ = "Lord Whopper of Fibbing";
/pp/;
sind die folgenden
Aussagen wahr: (Beachte, dass eq die Gleichheit von Strings bedeutet.)
$` eq "Lord Who";
$& eq "pp";
$' eq "er of Fibbing";
Zum Schluss des
Abschnittes über Muster-Wiederverwendung möchten wir noch darauf
aufmerksam machen, dass Variabeln, welche innerhalb der Schrägstriche
eines Vergleiches verwendet werden, interpoliert werden. Damit wird in
$search = "the";
s/$search/xxx/g;
jedes Vorkommen
von the durch xxx ersetzt. Falls jedes Vorkommen von there
ersetzt werden soll, kann nicht s/$searchre/xxx/ verwendet werden,
da der Versuch unternommen wird, die Variable $searchre zu interpolieren.
Falls hingegen der Variablenname in geschweifte Klammern gesetzt wird,
sieht der richtige Code wie folgt aus:
$search = "the";
s/${search}re/xxx/;
Uebersetzen
Die Funktion tr
ermöglicht die Uebersetzung von einzelnen Buchstaben. Die folgende
Anweisung ersetzt in der Variablen $sentence jedes a mit einem e,
jedes b mit einem d und jedes c mit einem f.
Der Ausdruck gibt die Anzahl gemachter Ersetzungen zurück.
$sentence =~ tr/abc/edf/;
Die meisten der
speziellen Codes für reguläre Ausdrücke können in der
Funktion tr nicht verwendet werden. Die folgende Anweisung zum Beispiel,
zählt die Anzahl Sterne in der Variablen $sentence und speichert sie
in der $count-Variablen ab.
$count = ($sentence =~ tr/*/*/);
Der Bindestrich
jedoch bedeutet immer noch einen Bereich ("zwischen"). Diese Anweisung
übersetzt $_ in Grossbuchstaben:
tr/a-z/A-Z/;
Uebung
Das aktuelle Programm
zählt die Zeilen, welche einen bestimmten String beinhalten. Aendere
das Programm so, dass es die Zeilen zählt, welche einen Doppelbuchstaben
enthalten. Diese Doppelbuchstaben sollen in Klammern ausgegeben werden.
Zum Beispiel
sollten folgende Zeilen erscheinen:
«30?» Fabio Hi(pp)in steht auf dem Tre(pp)enabsatz und zieht kräftig an Sophies
«Du, sag mal: Hast Du schon a(ll)es gezügelt?»
Ein bisschen interessanter
ist vielleicht eine Verallgemeinerung dieses Programmes. Wie möchten
die Suchstrings als Argumente übergeben. Angenommen das Programm heisse
countlines. Bei einem Aufruf
countlines first second etc
werden die Argumente
im Array @ARGV abgespeichert. Somit ist $ARGV[0] gleich first,
$ARGV[1]
gleich second und $ARGV[2] gleich etc.
Aendere das
Programm, sodass es ein Argument akzeptiert und nur diejenigen Zeilen
zählt, welche diesen String enthalten. Setze diese Vorkommnisse in
Klammern. Damit wird
countlines du
unter anderem die
folgende Zeile ausgeben:
022Blackcurrant-Büchse (du)rch die Luft, die er mit einem Hechtsprung auf den
Mehr String-Funktionen
Split
Eine sehr nützliche
Funktion in Perl ist die split-Funktion. Sie unterteilt einen String an
definierten Stellen und kopiert die Teile in einen Array. Diese Funktion
verwendet reguläre Ausdrücke für die Trennstellen und splittet
die $_-Variable, falls nichts anderes spezifiziert wird.
Sie funktioniert
folgendermassen:
$info = "Benno:Müller:Kaufmann:Hauptstrasse 14";
@personal = split(/:/, $info);
Dies hat den gleichen
Effekt, wie
@personal = ("Benno", "Müller", "Kaufmann", "Hauptstrasse 14");
Falls die Information
in der $_-Variablen gespeichert ist, können wir einfach schreiben:
@personal = split(/:/);
Falls die einzelnen
Felder durch eine beliebige Anzahl von Doppelpunkten unterteilt sind, können
wir einen regulären Ausdruck verwenden. Der Code
$_ = "Hugo:Huber::dipl. math.:::Dammweg 2";
@personal = split(/:+/);
bedeutet das gleiche
wie
@personal = ("Hugo", "Huber",
"dipl. math.", "Dammweg 2");
Hingegegen würde
$_ = "Hugo:Huber::dipl. math.:::Dammweg 2";
@personal = split(/:/);
den folgenden Array ergeben:
@personal = ("Hugo", "Huber", "",
"dipl. math.", "", "", "Dammweg 2");
Ein Wort kann in
Buchstaben, ein Satz in Wörter und ein Paragraph in Sätze aufgeteilt
werden:
@chars = split(//, $word);
@words = split(/ /, $sentence);
@sentences = split(/\./, $paragraph);
Im ersten Fall
wird der Null-String zwischen jedem Buchstaben erkannt, deshalb ist der
@chars-Array ein Array von Buchstaben, dh. ein Array von Strings der Länge
1.
substr
Eine weitere Funktion
die auf Strings operiert ist die substr-Funktion. Hier sind drei Beispiele,
wie sie verwendet wird:
substr("Once upon a time", 3, 4); # returns "e up"
substr("Once upon a time", 7); # returns "on a time"
substr("Once upon a time", -6, 5); # returns "a tim"
Das erste Beispiel
ergibt einen Substring der Länge 4, welcher an der 3. Stelle beginnt.
Beachte, dass der erste Buchstaben eines Strings den Index 0 hat!
Beim zweiten
Beispiel wird der letzte Parameter, die Länge des Substrings, weggelassen.
Das Resultat ist ein Substring, welcher von der angegebenen Stelle bis
zum Ende des Strings reicht.
Das dritte
Beispiel benützt einen negativen Index. Es ergibt einen Substring,
der an der 6. Stelle vom Ende des Strings an 5 Buchstaben lang ist.
Falls der negative
Index vor den Anfang des Stringes zeigt, wird Perl nichts zurückgeben
und eine Warnung ausgeben. Um das zu vermeiden, kann man einen String verlängern
unter Verwendung des x-operators, den wir früher erwähnt haben.
Zum Beispiel erzeugt der Ausdruck (" "x30) erzeugt 30 Leerzeichen.
substr
kann auch als lvalue verwendet werden (auf der linken Seite einer Anweisung):
$str = "It's a Perl World.";
substr($str, 7, 4) = "Small"; # It's a Small World
substr($str, 13, 0) = "Perl "; # It's a Small Perl World
Uebung
Ein nützliches
Werkzeug in der Verarbeitung von natürlichen Sprachen ist die Konkordanz.
Sie erlaubt die Darstellung einer bestimmten Zeichenfolge in ihrem unmittelbaren
Kontex. Zum Beispiel wird ein Konkordanzprogramm mit dem Suchstring 'the'
angewendet auf ein bestimmtes File die folgende Ausgabe erzeugen. Beachte
die Darstellung des Suchstringes in einer vertikalen Zeile.
discovered (this is the truth) that when he
t kinds of metal to the leg of a frog, an e
rrent developed and the frog's leg kicked,
longer attached to the frog, which was dea
normous advances in the field of amphibian
ch it hop back into the pond -- almost. Bu
ond -- almost. But the greatest Electrical
ectrical Pioneer of them all was Thomas Edi
Wir wollen ein
solches Programm als Uebungsbeispiel für unser File roman5.txt mit
dem Suchstring du schreiben. Beachte die folgenden Hinweise:
-
Das ganze File
soll in einen Array eingelesen werden (dies ist natürlich im Allgemeinen
nicht angebracht, da das File sehr gross sein kann, aber wir wollen uns
jetzt nicht darum kümmern.) Jede Zeile des Files ist ein Element des
Arrays.
-
Die chop -Funktion
mit einem Array als Parameter schneidet den letzten Buchstaben jedes Array-Elementes
ab.
-
Wie wir schon gesehen
haben, kann der gesamte Array mit folgender Anweisung zusammengefügt
werden: $text = "@lines";
-
Verwende die split-Funktion
mit dem Suchstring als regulärer Ausdruck für die Trennstelle,
an welcher der Text unterteilt werden soll. Das Resultat ist ein Array
aller Substrings, welche vom Suchstring eingeschlossen sind.
-
Drucke der Reihe
nach jedes Arrayelement, den Suchstring und das nächste Arrayelement
aus
-
Beachte, dass das
letzte Element des Arrays @food den Index $#food hat.
Soweit so gut.
Jedoch stehen die Suchstrings noch nicht untereinander in einer Zeile.
Um das zu erreichen benötigen wir die substr-Funktion.
Binäre Daten und Files
Als C-Programmierer
kennt man die Funktionen, um in binären Files zu manövrieren.
In Perl ist es sehr ähnlich: Für Lesen gibt es read, für
Schreiben print (nein, nicht write!), für Positionieren seek und um
die aktuelle Position im File zu erhalten tell. Diese Funktionen gelten
auch für Textfiles, werden jedoch meistens in Files mit fester Recordlänge
(fixed record length) verwenden, wo beliebiger Zugriff auf einzelne Records
(random access) durch einfache Berechnungen möglich ist.
Zuerst machen
wir als einfaches Beispiel die Kopie eines Files mit read und print:
open FROM, "InFile";
open TO, ">OutFile";
while (read FROM, $buf, 16384) {
print TO $buf;
}
close FROM;
close TO
open und close
funktionieren wie früher besprochen.
( Es gäbe
auch noch eine einfachere Möglichkeit, ein File zu kopieren: Mit dem
Modul File::Copy. )
binäre
Daten
Nehmen wir an,
wir hätten ein File, welches von einem C-Program geschrieben wurde
und zwar mit fester Recordlänge, dh. mit fwrite einen struct
mit bekannter Definition. Wir wollen diese Records auslesen und den Inhalt
der einzelnen Felder zugreifen. Dazu verwenden wir die Funktionen read
und unpack. unpack benötigt als Parameter ein Template, welches die
Struktur des Records (struct) beschreibt und einen String, welcher
den Record beinhaltet. Das Template ist eine Folge von Buchstaben, welche
die Reihenfolge und Art der einzelnen Felder des Records beschreibt:
-
A,a ASCII String
-
b,B Bit String
-
h,H Hex String
-
c,C Signed/Unsigned
Char
-
s,S Signed/Unsigned
Short
-
i,I Signed/Unsigned
Integer
-
l,L Signed/Unsigned
Long
-
p Pointer to a
null-terminated string.
Weitere Templates
sind unter der Funktion pack zu finden.
Ein Teil des
C-Codes für obiges Beispiel sieht wie folgt aus:
struct{char st[4]; int in; double d;} gaga;
fwrite(&gaga, sizeof(gaga) 1 , fp) (* FILE *fp *)
Perl-Code:
$template = "a4 i d";
$len = length pack($template,'',0,0)
read(FP,$rec,$len) # open FP, "filename";
($str,$in,$d) = unpack($template,$rec);
Mit pack kann ein
Record wie in C erzeugt werden. Wir brauchen diese Funktion hier, um die
Länge des Records zu bestimmen.
Formattierte Ausgabe
Perl liefert einen
Mechanismus um einfache Reports und Tabellen auszugeben, der über
die Möglichkeiten der print- und printf-Funktion hinausgeht. Man deklariert
das Layout der Ausgabe mit format und gibt die einzelnen Records mit write
aus. Die Deklaration format kann irgendwo im Programm erfolgen und hat
die folgende Syntax:
format NAME =
FORMLIST
.
NAME ist der Formatname
und wird defaultmässig dem gleichnamigen Filehandle zugeordnet. Falls
er weggelassen wird, wird STDOUT angenommen.
FORMLIST besteht
aus einer Folge von Zeilen, die jede entweder eine Kommentarzeile sein
kann, mit einen #-Zeichen am Anfang, eine Format-Zeile, welche das Aussehen
der Ausgabe beschreibt, oder eine Parameterzeile, welche die auszugebenden
Variablen zu der vorangehenden Format-Zeile angibt. Mit der gleichen Syntax
kann das Format für eine oder mehrere Kopfzeilen angegeben werden.
Der Name von Kopfzeilen-Formaten hat die Form FILEHANDLE_TOP, resp. für
STDOUT nur TOP. Es gibt wiederum eine Anzahl von Spezialvariablen, welche
im Zusammenhang mit Formaten gebraucht werden können. Zum Beispiel
ist $~ gleich dem Namen des aktuellen Ausgabeformates, resp. $^
derjenige, des aktuellen Kopfzeilen-Formates.
Beispiel: Wir
möchten nun das binäre File, welches wir oben gelesen habe, schön
formattiert ausgeben:
format TOP =
Binaeres File
STRING INTEGER DOUBLE
----------------------------------
.
format =
# String linksbuendig, Integer zentriert, Double rechtsbuendig
@<<<< @|||||| @>>>>>
$str,$in,$d
.
while (read(FP,$rec,$len)) {
($str,$in,$d) = unpack($template,$rec);
write;
}
Für weitere
Details zu Formaten, wende man sich an das Manual.
Uebung
Schreibe ein Programm,
welches das File /var/adm/wtmp eines UNIX-Systemes ausliest. Dieses File
enthält die Informationen über die Logins des Systems.
Formattiere die Ausgabe mit format. Die Struktur des Files /var/adm/wtmp
ist systemabhängig. (Siehe man utmp).
Subroutinen
Wie jede gute
Programmiersprache können in Perl eigene Funktionen programmiert werden.
Man nennt sie in Perl Subroutinen (wie in Fortran!?).
Sie können
irgendwo im Programm platziert werden. Normalerweise wird man sie an den
Anfang oder ans Ende des Programmes stellen. Wie in C kann eine Subroutine
deklariert und später definiert werden unter Verwendung der Compilerdirektive
use
subs.
sub NAME; # Deklaration
sub NAME(PROTO); # Deklaration mit Prototypen
sub NAME BLOCK # Definition
sub NAME(PROTO) BLOCK # Definition mit Prototypen
Beispiel:
sub mysubroutine
{
print "Dies ist eine langweilige Subroutine.\n";
print "Sie macht immer das gleiche!\n";
}
Alle folgenden
Anweisungen rufen diese Subroutine auf. Beachte, dass der Buchstabe &
am Anfang des Namens stehen muss. (V5: nicht mehr nötig, aber empfohlen.)
&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.
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.
Häufig
möchte man die Elemente von @_ einer eigenen lokalen Variablen
zuordnen, etwa um die Lesbarkeit zu verbessern. Die folgende Subroutine
testet, ob ein String Substring eines anderen ist, ohne die Leerzeichen
zu berücksichtigen:
sub inside
{
my ($a, $b); # Erzeuge lokale Var.
($a, $b) = ($_[0], $_[1]); # Param. zuordnen
$a =~ s/ //g; # Leerzeichen aus lok.
$b =~ s/ //g; # Var. 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
local war
in Perl 4 die einzige Möglichkeit lokale Variabeln zu deklarieren.
Aus Kompatibilitätsgründen und für Spezialfälle ist
es noch verfügbar.
my ist
die neuere (abPerl 5) und effizientere Art 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. $\ zu lokalisieren, muss
local
verwendet werden.
Uebung
Mache aus der FOR-Schleife
der letzten Uebung 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.
'Type
Globs' und Referenzen
'Type
Globs'
Typeglobs
sind Einträge in die Symboltabelle. (Diese ist im Hash %:: abgespeichert.)
In Perl kann man alle Objekte mit einem bestimmten Namen referenzieren,
indem man diesen Namen mit dem Präfix * versieht: *foo. Das
nennt man dann type globbing, weil der Stern als Wildcard
für alle anderen Präfix-Buchstaben wie $, %, & stehen
kann. Folgendes Beispiel soll diesen Sachverhalt erhellen:
$foo = 100;
@foo = ('aa','bb','cc');
sub foo {
print "I am foo\n";
}
sub deref {
local(*bar) = @_;
print $bar[0],"\n";
print $bar,"\n";
&bar;
}
print "Ref: ",*foo,"\n";
&deref(*foo);
Die Ausgabe dieses
Programmes sieht wie folgt aus:
Ref: *main'foo
aa
100
I am foo
In Perl 4 wurde
dieser Mechanismus verwendet, um die Uebergabe von Referenzen an Subroutinen
zu simulieren. In Perl 5 werden dafür echte Referenzen verwendet (siehe
unten). Natürlich funktioniert der alte Mechanismus auch in modernen
Versionen.
Referenzen
Mir dem type
globbing erhält man symbolische Referenzen, dh. sie beinhalten
den Namen einer Variablen, vergleichbar mit einem symbolischen Link in
einem Unix-Filesystem. In Perl 5 gibt es auch sogenannte harte Referenzen.
Sie zeigen direkt auf das der Variabeln zugrundeliegende Objekt, welches
eine skalare Variable, ein Array oder ein assoziativer Array (Hash) sein
kann, aber auch eine Subroutine oder ein Filehandle. Diese Referenzen sind
'intelligent'. Sie führen Buch über die Anzahl Referenzen auf
ein Objekt und geben das Objekt frei, sobald diese Anzahl auf Null geht.
Eine Variable
wird von Perl nie implizit dereferenziert. Falls eine skalare Variable
eine Referenz ist, wird sie sich immer als skalare Variable verhalten und
nicht als der Typ, den sie referenziert. Diese Tatsache hat syntaktische
Konsequenzen (siehe perldsc- , resp. perlLoL- Manpage).
Erzeugen von Referenzen
-
Mit dem Backslash-Operator:
$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*STDOUT;
-
Als Referenz zu
einem anonymen Array, Hash oder Funktion:
$arrayref = [1, 2, ['a', 'b', 'c']];
$hashref = {'Adam' => 'Eve', 'Clyde' => 'Bonnie');
$coderef = sub { print "Boink!" };
-
Referenzen werden
häufig durch spezielle Subroutinen, den Konstruktoren zurückgegeben:
$objref = new Doggie (Tail => 'short', Ears => 'long');
$objref->bark(); # Aufruf einer Methode
-
Referenzen zu Filehandles
werden durch Referenzen zu einem Typeglob erzeugt. Folgendes Beispiel
zeigt, wie ein Filehandle als Parameter einer Subroutine übergeben
wird:
splutter(\*STDOUT); # Aufruf
sub splutter { # Deklaration
my $fh = shift;
print $fh "gugus\n";
}
Dereferenzieren
-
Ueberall, wo man
einen Identifier als Teil eines Variablen- oder Subroutinennamens schreiben
würde, kann dieser Identifier durch eine einfache skalare Variable,
welche eine Referenz auf den gewünschten Typ darstellt, ersetzt werden.
$bar = $$scalarref;
push(@$arrayref, $filename);
$$arrayref[0] = "Januar";
$$hashref{"KEY"} = "VALUE";
&$coderef(1,2,3);
print $globref "output\n";
-
Ueberall, wo man
einen Identifier als Teil eines Variablen- oder Subroutinennamens schreiben
würde, kann dieser Identifier durch einen BLOCK, welcher eine Referenz
auf den gewünschten Typ zurückgibt, ersetzt werden.
$bar = ${$scalarref};
push(@{$arrayref}, $filename);
${$arrayref}[0] = "Januar";
${$hashref}{"KEY"} = "VALUE";
&{$coderef}(1,2,3);
In diesen Fällen
ist es natürlich überflüssig die geschweiften Klammern zu
verwenden. Aber da ein Block einen beliebigen Ausdruck beinhalten kann,
gibt es vernünftigere Beispiele:
&{ $dispatch{$index} }(1,2,3); # Aufruf der korrekten Subroutine
-
Als syntaktische
Variante geht auch:
$arrayref->[0] = "Januar";
$hashref->{"KEY"} = "VALUE";
Die linke Seite
vom Pfeil kann irgendein Ausdruck sein, welcher eine Referenz zurückgibt.
$array[$x]->{"foo"}->[0] = "Januar";
Vor dieser Anweisung
könnte $array[$x] undefiniert sein, wird aber an dieser Stelle automatisch
zu einer Referenz auf einen Hash. Dasselbe gilt analog für $array[$x]->{"foo"}.
Die Pfeile zwischen den Klammern müssen nicht geschrieben werden:
$array[$x]{"foo"}[0] = "Januar";
-
Eine Referenz kann
aber auch eine Referenz auf ein Objekt (zu einer Klasse) sein. Dann gibt
es vermutlich Methoden, welche durch diese Referenz zugegriffen werden
können:
$obj->methode($param);
Wir werden im nächsten
Kapitel mehr davon hören. Und dann gibt es noch die perlobj-Manpage.
Mit den
Referenzen von Perl 5 ist es einfach mehrdimensionale Datenstrukturen (Arrays
von Arrays, Arrays von Hashes, Hashes von Subroutinen etc. zu erzeugen
(siehe perldsc- resp. perlLoL-Manpage).
Weitere Angaben
über Referenzen findet man in den perlref -Manpage.
Referenzen als
Parameter von Subroutinen
Manchmal möchte
man nicht einen Array als Wertparameter übergeben, sondern innerhalb
der Subroutine mit der globalen Variablen arbeiten (PASCAL: VAR-Parameter).
Natürlich ist es schneller eine Referenz zu übergeben, anstelle
eines ganzen Arrays, daneben ist es die einzige Möglichkeit, mehrere
Arrays als Parameter zu übergeben. (Warum?)
Das folgende
Beispiel gibt die letzten Elemente von einer Liste von Arrays aus:
@letzte = popmany( \@a, \@b, \@c, \@d );
sub popmany {
my $aref;
my @retlist = ();
foreach $aref (@_) {
push @retlist, pop @$aref;
}
return @retlist;
}
Das ist ja alles
sehr schön, aber wie bekomme ich mehrere Arrays oder Hashes als Rückgabewerte?
Wie wär's mit folgendem:
($aref, $bref) = func(\@a, \@b);
print "@$aref has more then @$bref\n";
sub func {
my ($cref, $dref) = @_;
if (@$cref > @$dref) {
return ($cref, $dref);
} else {
return ($dref, $cref);
}
}
Uebung
Man nehme die Uebung
des letzten Kapitels und tausche die Parameter der Subroutine aus. Damit
das funktioniert, muss man eine Referenz auf den Array der Textstücke
übergeben und in der Subroutine den Array dereferenzieren.
Module
Packages
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.
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
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.
Module
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()!!
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
Uebung 1
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:
-
readdir
-
`ls` resp qx{ ls
}
-
Pipe von /bin/ls:
open(FILES,"/bin/ls *|");
while ($File = <FILES>) {..}
Uebung 2
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;
Einführung in Perl 5 Objekte
Viele Leute
schrecken vor den praktischen Perl5-Modulen zurück, weil diese mit
Objekten zu tun haben. Und das ist ja schon mal verdächtig und tönt
nach etwelchen Schwierigkeiten ohne entsprechend nützlich zu sein.
Auf der anderen
Seite führen gewisse Probleme automatisch hin zu Objekten. Das macht
den Leuten Angst. Unnötigerweise.
Es ist ein riesiger
Unterschied genügend über OO-Programmierung zu wissen, um Module
zu verwenden , oder um Module selber entwerfen und implementieren
zu können. Man befürchtet das letztere können zu müssen
um Zugang zum ersteren zu erhalten. Das ist weit weg von der Realität.
Man muss nicht
viel wissen um Module verwenden zu können. Man lädt einfach die
Library und ruft die dokumentierten "Konstruktoren" auf. "Konstruktoren"
sind die Dinge, welche neue Objekte erzeugen. Häufig werden sie new
genannt.
In Perl5 werden
ein oder zwei neue Konzepte verwendet, welche Sie vielleicht bisher noch
nie gesehen haben:
-
Die Anweisung use
Module lädt ein Modul mit dem Namen Module.pm (zur Kompilationszeit)
und fügt die exportierten Namen in Ihren Namensraum ein. Die Anweisung
require
Module lädt das Modul ebenfalls, aber erst zur Laufzeit und importiert
keine Namen.
-
Der Pfeil-Operator
für die Dereferenzierung -> bedeutet ein Aufruf einer Methode
(Subroutine) eines Objektes. In OO-Slang sagt man auch 'dem Objekt eine
Message senden'. Dabei braucht man keinerlei Kenntnisse über den Aufbau
des Objektes. Es ist einfach eine Black Box, welche Subroutinen zur Verfügung
stellt. Das ist alles.
-
Die folgenden zwei
Zeilen sind aequivalent. Die zweite Zeile ist jedoch syntaktisch ein wenig
klarer:
$obj = new CGI;
$obj = CGI->new();
Wie jeder andere
Unterprogrammaufruf, kann eine Methode irgend etwas zurückgeben, sogar
ein anderes Objekt.
use LWP::UserAgent;
$ua = new LWP::UserAgent;
$ua->agent("Mozilla/5.0PlatinumB3"); # hee :-)
$req = new HTTP::Request GET => 'http://perl.com/perl/';
$req->header('Accept' => 'text/html');
# send request
$result = $ua->request($req);
# check the outcome
if ($result->is_success) {
print $result->content;
} else {
print "Error: " . $result->code
. " " . $result->message;
}
Das wär's.
Das ist alles. Mehr braucht man nicht um Module in Perl zu verwenden.
Hier sind noch
ein paar Beispiele für den Gebrauch von perl WWW-Modulen:
use CGI;
$req = CGI->new();
use CGI::Imagemap;
$map = CGI::Imagemap->new();
use HTML::Parse;
$html = parse_htmlfile("test.html");
use URI::URL;
$url = URI::URL->new('gisle.gif','http://www.com/%7Euser');
use HTTP::Request;
$hreq = HTTP::Request->new('GET', 'http://www.perl.com/');
Ich glaube nicht,
dass man ein Smalltalk- oder C++-Superguru sein muss, um mit diesen Dingen
umzugehen. Aber falls Sie wirklich mehr darüber lernen möchten,
können Sie die perlobj manpage konsultieren. |