Perl - kurz und bündig
| Kommentare
werden mit # eingleitet und gehen bis zum Ende der Zeile |
| Anweisungsblöcke
sind in {} eingeschlossen und enthalten eine Folge von Anweisungen |
| if() {} else {}
Bedingte Abfrage,
kann umgedreht werden:
$a=4 if ($b=0);
zu lesen als: a=4 wenn b=0 |
| unless() {}
Wenn-Nicht-Abfrage |
| if() {} elsif() {} else {}
erweitertes if(): mehrere bedingte Abfragen |
| while() {}
wiederholt Anweisungsblock solange, bis die Bedingung nicht mehr stimmt |
| until() {}
wiederholt Anweisungsblock solange, bis die Bedingung stimmt |
| do {} while()
do {} until()
analog while() bzw. until(), nur daß hier der Anweisungsblock in jedem
Fall mindestens einmal ausgeführt wird |
| for() {}
initialisiert einen Ausdruck, testet ihn, führt den Anweisungsblock aus und verändert
den Ausdruck. Anschließend wird solange getestet, der Anweisungsblock ausgeführt und der
Ausdruck verändert, bis der Test fehlschlägt,
for($i=0; $i<scalar(@array); ++$i) {...} |
| foreach $var () {}
arbeitet eine Liste ab, weist jeweils $var den Wert zu und führt damit den
Anweisungsblock aus. Statt $var kann $_ verwendet werden,
foreach $datei (@dateiliste) {...}
foreach $key (keys %hash) {...} |
| Funktionsaufrufe müssen nicht zwingend mit Klammern geschrieben
werden. Funktionen, die eine Liste als Parameter erwarten, müssen eine Liste
(sprich (elem1,elem2,...) ) übergeben, zu der -wie das
Listenkonstrukt vorschreibt- runde Klammern gesetzt werden müssen.
Alle anderen können ohne runde Klammern auskommen, es sei denn, die
Funktion kommt generell nicht mit Listen klar, sondern nur mit einem Skalar
oder keinem Übergabewert.
Die Klammersetzung ist unabhängig vom Rückgabewert.
push(@array,'neuesElement');
ist gleich
push @array,'neuesElement';
Falsch wäre z.B.
@schluesselliste = keys(%hash1,%hash2);
Richtig dagegen:
@schluesselliste = keys(%hash1);
@schluesselliste = keys %hash1;
Ebenso kann die aktuelle UNIX-Zeit wie folgt ermittelt werden:
$now = time;
$now = time(); |
Zahlen: Literale, Operatoren und Funktionen
Literale |
| Variable: $var |
| Ganzzahlen |
| Fließkommazahlen, auch in wissenschaftlicher Form |
Intern wird grundsätzlich mit Fließkomma gerechnet |
Operatoren |
| Zuweisen mit = |
| Grundrechenarten: +, -, *, / |
| Potenz ** und Modulo % |
| Vergleichsoperatoren: <, <=, ==, >=, >, != |
| binäre Zuweisungen: +=, -=, *=, /=, **=, %=, .= |
| Autoinkrement ++ und Autodekrement -- |
|
Funktionen |
|
Zeichenketten: Literale, Operatoren und Funktionen
Literale |
| Variable: $var |
| Zeichenketten in einfachen Anführungszeichen
in ihr werden keinerlei Ersetzungen durch \-Codes durchgeführt, es gelten jedoch 2
Ausnahmen: '\'' stellt das einfache Anführungszeichen dar, ohne daß es die Zeichenkette
beendet und '\\' stellt den Backslash dar |
| Zeichenketten in doppelten Anführungszeichen
in diesen Zeichenketten sind ähnliche \-Codes wie die von C erlaubt, wie z.B.
"\n". Zudem werden Variablen jeder Art ersetzt (mit Ausnahmen) |
|
Operatoren |
| Zuweisen mit = |
| Aneinanderketten von Zeichenketten mit . (Punkt) |
| Vergleichsoperatoren: lt, le, eq, ge, gt, ne (analog den
Zahlen); in neueren Perl sind diese deprecated und durch die
üblichen Vergleichsoperatoren ersetzt worden |
| Wiederholungsoperator x: Anzahl Wiederholungen der
Zeichenkette,
z.B. "Haus" x 5 ergibt "HausHausHausHausHaus"
|
|
Funktionen |
| chop(str)
schneidet das letzte Zeichen des Strings str ab |
| chomp(str)
entfernt nur ein Newline (\n) als letztes Zeichen von str ; ist keines dort,
dann bleibt sie unverändert,
nützlich zum Einlesen von Zeilen aus Dateien:
while(<IN>) {
chomp;
# Variable $_ enthält nun Zeile ohne Newline
} |
|
Arrays bzw. Listen: Literale, Operatoren und Funktionen
Literale |
| Variable: @var |
| in runde Klammern eingeschlossene skalare Daten, die nicht
zwingend vom selben Typ sein müssen,
@array = (1,4,9); |
| Anlegen eines Arrays in Form einer Referenz über eckige
Klammern:
$refToArray = [1,4,9];
Dann kann auf die Elemente mit dem Verweisoperator zugegriffen
werden:
print $refToArray->[1];
oder durch Rückwandlung in ein Array:
print $$refToArray[1];
Funktionen, die keine Referenzen mögen, erhalten den
nativen Datentypen durch Casten:
foreach $item (@$refToArray) {...} |
|
Operatoren |
| Listenkonstruktor .. , der eine Liste von Elementen zwischen
den Anfangs- und Endwerten anlegt, die jeweils um den Wert 1 voneinander getrennt sind,
arbeitet nur mit ganzzahligen Indexen!
z.B. (1.2 .. 5.5) ergibt (1,2,3,4,5) |
| Zugriff auf einzelne Elemente mit $var[index] |
| Zugriff auf mehrere Elemente (genannt Slice)
mit $var[index,...] oder über Listenoperator $var[start..ende] |
| Referenzoperator $ : Liefert eine Referenz auf ein Element. Zugriff auf einzelne Elemente mit $$var[index] |
|
Funktionen |
| push(@var,$var,...)
$var,... am Ende der Liste @var anhängen |
| pop(@var)
entfernt und liefert letztes Element der Liste |
| shift(@var)
entfernt und liefert erstes Element der Liste |
| unshift(@var,$var,...)
$var,... am Anfang der Liste @var anhängen |
| reverse(@var)
dreht die Reihenfolge der Elemente in der Liste um |
| sort(@var)
sortiert die Liste in der einfachsten Form als Zeichenketten, auch wenn es Zahlen sind |
| chomp(@var)
entfernt nur ein Newline (\n) als letztes Zeichen von jedem Element in der Liste; ist
jeweils keines dort, dann bleiben sie jeweils unverändert |
| grep(regexpr,@var)
filtert anhand eines regulären Ausdrucks aus einer Liste passende Elemente und liefert
wieder eine Liste,
z.B. @filtered = grep(/^#/,@elements);
(liefert alle Elemente, beginnend mit '#') |
| scalar(@var)
wandelt ein Array in ein Skalar um, indem es die Länge des Arrays
zurückgibt. Bei
for($i=0; $i<@array; ++$i) {... $a=$array[$i]; ...}
erkennt Perl selbst, daß die Vergleichsbedingung nur ein Skalar sein kann
und wendet von sich aus scalar() an. Sicherheitshalber sollte
man das scalar() jedoch anwenden:
for($i=0; $i<scalar(@array); ++$i) {... $a=$array[$i]; ...} |
Für SM-Programmierer :-):
| qw(words)
erzeugt eine Liste aus durch Leerzeichen getrennten Wörtern; die Wörter dürfen nicht in
Anführungszeichen stehen |
|
Hashes: Literale, Operatoren und Funktionen
(Hash: ein Schlüssel-Wert-Paar)
Literale |
| Variable: %var |
| in runde Klammern eingeschlossene skalare Daten, die
paarweise Schlüssel und Wert enthalten,
%hash = ('auto'=>'bmw','raeder'=>4); |
| Anlegen eines Hashes in Form einer Referenz über geschweifte
Klammern:
$refToHash = {'auto'=>'bmw','raeder'=>4};
Dann kann auf die Elemente mit dem Verweisoperator zugegriffen
werden:
print $refToHash->{'auto'};
oder durch Rückwandlung in einen Hash:
print $$refToArray{'raeder'};
Funktionen, die keine Referenzen mögen, erhalten den
nativen Datentypen durch Casten:
foreach $item (keys %$refToHash) {...} |
|
Operatoren |
| Zugriff auf einzelne Elemente mit $var{key} |
| Zugriff auf mehrere Elemente (genannt Slice)
mit @var{key,...} |
| reverse %var
erzeugt neuen Hash, der die Werte als Schlüssel und die Schlüssel als Werte enthält.
Achtung: Mehrere identische Werte werden zu einem(!) Schlüssel, hierbei ist nicht
festgelegt, welcher letztendlich gesetzt wird. |
|
Funktionen |
| keys()
erzeugt eine Liste aller Schlüssel |
| values()
erzeugt eine Liste aller Werte in der Reihenfolge, wie sie bei keys() zurückgegeben
würde |
| each()
liefert ein Schlüssel-Wert-Paar und erhöht intern einen Zählindex, so daß alle
Hasheinträge abgearbeitet werden können. Die Reihenfolge der Einträge ist dabei nicht
festgelegt. |
| Die Länge eines Hashes ermittelt man leicht aus der Länge der
vorhandenen Keyliste:
$laengeDesHash = scalar(keys(%hash)); |
|
Literale |
| Variable in <> eingeschlossen |
| Zeileneingabeoperator <> (ohne Name darin) liest Daten
aus den Dateien, die bei der Übergabe beim Start vom Programm angegeben werden |
| <STDIN> liest von Standardeingabe |
|
Operatoren |
| Zuweisungen:
| $var = <name> weist $var eine gelesene Zeile zu |
| @var = <name> weist @var alle gelesenen Zeilen in Form
einer Liste zu |
| $_ enthält eine gelesene Zeile, wenn keine Variable
angegeben wird |
|
|
Funktionen |
| open(filehandle,file specifier) Öffnet eine Datei. Der file specifier enthält neben dem Dateinamen
vorangestellte Steuerzeichen, die den Modus der Datei anzeigen:
| ohne Steuerzeichen wird die Datei zum Lesen geöffnet |
| mit vorangestelltem '>' wird die Datei zum Schreiben
geöffnet |
| mit vorangestelltem '>>' wird die Datei zum Anhängen
geöffnet |
| mit vorangestelltem '|' wird eine benannte Pipe geöffnet |
Die Funktion liefert undef, sollte die Datei mit
dem gewünschten Modus nicht geöffnet werden können
|
| close(filehandle) schießt eine zuvor mit open() geöffnete Datei
|
| print filehandle string gibt eine Zeichenkette über den Filehandle aus. Zu beachten ist,
daß zwischen Filehandle und Zeichenkette kein Komma stehen darf. Wird
Filehandle weggelassen, dann nimmt Perl das immer geöffnete Filehandle STDOUT an.
Wichtig: Die Funktion write dient nicht
der Ausgabe von Daten in eine Datei!
|
| read filehandle, scalar, length [, offset] liest die gegebene Anzahl Bytes aus der Datei mit dem Filehandle in
die skalare Zeichenkette. Der Offset zeigt nur die Position an, an der die gelesene
Zeichenkette im Skalar eingefügt wird.
|
|
Verzeichnisse |
Verzeichnisse können auch ausgelesen
werden:
| opendir(dirhandle,directoryname) Öffnet ein Verzeichnis, um die darin befindlichen Dateien
verarbeiten zu können
|
| closedir(dirhandle) schließt
ein zuvor mit opendir() geöffnetes Verzeichnis
|
| readdir(dirhandle) liest
im Listenkontext alle im geöffneten Verzeichnis befindlichen Dateien ein (einschließlich
'.' und '..') und im Skalarkontext den nächsten Verzeichniseintrag
|
|
Format |
| Operator/Ausdruck/Optionen |
| Operator/Ausdruck/Ersetzungsteil/Optionen |
Wirkt grundsätzlich auf die Variable $_. |
Operator |
Operatoren legen fest, was der
reguläre Ausdruck bewirken soll:
s |
Erzetze gefundenes Muster mit Zeichenkette |
m |
Vergleiche Muster mit Zeichenkette; der
Operator kann weggelassen werden. Er ist jedoch nötig, wenn das Begrenzungszeichen
verändert werden muß (s.u.) |
|
Ausdruck |
Im Ausdruck ist zulässig:
| Ein Zeichen, das an der gegebenen Stelle erwartet wird |
| Ein . (Punkt), der auf alle Zeichen außer Newline paßt |
| Muster für mehrere passende Zeichen an einer Stelle in [];
hierbei sind Zeichenbereiche (z.B. 0-9) möglich. Soll das Zeichen '-' oder '\'dargestellt
werden, dann wird jeweils ein '\ ' vorangestellt, z.B. [0-9\-] |
| Für Muster für mehrere nicht passende Zeichen gilt
gleiches wie bei [], nur daß vor alle Zeichen ein ^ gesetzt wird, z.B. [^0-9\-]
|
| Multiplikator * : null- oder mehrmals das unmittelbar
vorhergehende Zeichen bzw Zeichenklasse |
| Multiplikator + : ein- oder mehrmals das unmittelbar
vorhergehende Zeichen bzw Zeichenklasse |
| allgemeiner Multiplikator {s,e} : mindestens s mal und
höchstens e mal das unmittelbar vorhergehende Zeichen bzw Zeichenklasse |
| Klammern () als Zwischenspeicher: der in der Klammer
eingeschlossene Ausdruck wird für weitere Verwendung gespeichert und kann mit \n (mit n =
1, 2, ..) wiederholt werden, z.B. ist der Wert in Klammern bei fred(.)barney\1
ein X , dann wird bei \1 auch ein X erwartet. |
| Auswahlen werden mit | angeboten, es muß dann eines der
angegebenen passen. Bei mehreren Zeichen müssen die Auswahlen in ()
gesetzt sein. |
| Ankermuster legen bestimmte Positionen fest, z.B.
Wortgrenzen \w, Satzanfang ^, Satzende $. |
|
Ersetzungsteil |
Je nach Operator dient sie einem
bestimmten Zweck:
| Operator s
| Option e
| Ersetzungsteil stellt einen Perl-Code dar, der ausgeführt
wird und eine Zeichenkette liefert. Dies kann auch eine selbst zusammengestellte
Zeichenkette sein, wobei man die Anführungszeichen für die Zeichenkette nicht vergessen
darf |
|
| sonstige Optionen
| Erzetze gefundenes Muster mit dieser Zeichenkette |
|
|
| Operator m
| er hat keinen Ersetzungsteil, da der Operator m nur
vergleicht und keine Aktion auf das gefundene Muster ausführt |
|
|
Optionen |
Je nach Operator dient sie einem
bestimmten Zweck:
i |
Groß-/Kleinschreibung ignorieren |
g |
alle Auftreten des regulären Ausdrucks betrachten, sonst nur das erste |
m |
betrachte Zeichenkette als eine Zeile, auch wenn '\n'
enthalten sind |
s |
betrachte '\n' nicht als Zeilenende |
e |
führe den Ersetzungsteil als Programmcode aus, statt ihn
nur zu ersetzen |
|
Anmerkungen |
| Ändern des Begrenzungszeichens
mit z.B. m#^/usr/local/bin# läßt sich das # statt dem / als
Begrenzungszeichen verwenden. Wichtig dabei ist, daß der Operator m
vorangestellt wird! |
| Auswählen eines anderen Ziels (der =~-Operator)
Statt $_ läßt sich jede beliebige Variable verändern:
$var =~ <regulärer Ausdruck> |
| Variableninterpolation
Eine Variable in einem regulären Ausdruck wird erst aufgelöst und dann zum
Mustervergleich herangezogen,z.B.:
$var="Vogel";
if ($text =~ /\b$var\b/) { ... }
liefert aufgelöst
if ($text =~ /\bVogel\b/) { ... }
Soll das $ selbst Teil des Strings sein, einfach escapen zu \$ . |
| Besondere nicht-beschreibbare Variablen
| $1, $2,... enthalten die Werte von \1, \2, ... |
| $& enthält Teil der Zeichenkette, die zum regulären
Ausdruck paßt |
| $` enthält Teil der Zeichenkette vor $& |
| $´ enthält Teil der Zeichenkette nach $& |
|
|
Funtionen |
| split(regExpr,$var)
teilt $var in Teile auf, deren Trennzeichen bzw. Trenntexte auf den regulären Ausdruck
passen, z.B.:
split(/\+/,"Ich+bin+ein+Beispiel")
teilt die Zeichenkette in die Wörter Ich , bin , ein
und Beispiel auf. |
| join($var,@var)
fügt eine Liste @var von Elementen mit jeweils einem Text $var zusammen zu eine
Zeichenkette,
$erg = join("+",('Ich','bin','gut!'));
liefert Ich+bin+gut! |
|
Notwendig |
Um mit Socketverbindungen arbeiten zu
können, muß das Package Socket vor der ersten Anwendung eingebunden werden:
use Socket;
|
Verbindungsaufbau |
Der Ablauf gliedert sich in drei
Schritte:
- Überprüfung, ob die Ziel-Adresse überhaupt bekannt ist,
indem die Adresse per DNS aufgelöst wird:
$iaddr
= inet_aton($address)
inet_aton() liefert eine 4 Bytes lange
Zeichenkette mit der zeichencodierten IP-Adresse,
$iaddr = inet_aton('hitserver.hi-tier.de');
- Öffnen des Socket und sichern in einem Handle:
socket(SOCKETHANDLE,PF_INET,SOCK_STREAM,getprotobyname('tcp'))
Liefert undef, sollte der eigene Socket nicht
geöffnet werden können.
Mit den Parametern wird eine Internet-Verbindung und ein
Stream über das Protokoll TCP initialisiert. Andere Parameter wären z.B. mit
UDP-Protokoll.
- Nach offenem Socket läßt sich nun eine Verbindung zwischen
dem eigenen Socket und dem Port am Zielrechner öffnen:
connect(SOCKETHANDLE,sockaddr_in($port,$iaddr))
sockaddr_in($port,$iaddr) packt die Portnummer und die
IP-Adresse in ein internes Format für den Funktionsaufruf in connect(). Mit dem Handle
für die Socketverbindung wird nun anhand der Zieladresse die Verbindung aufgebaut.
|
Verbingungsabbau |
Es genügt, wenn der Socket-Handle
geschlossen wird:
close SOCKETHANDLE
Den Rest erledigt Perl wegen seiner objekt-orientierten
Pakete selbst. |
Funktionen |
| $ipaddr = join('.',unpack("CCCC",$iaddr)) |
Um die gepackte Form der IP-Adresse (von inet_aton())
in der korrekten und leserlichen Form weiterverwenden zu können, wird diese damit als numerische IP
aufbereitet.
|
| Eigene Funktionen werden mit sub {} definiert,
sub vergleich {
return ($anzahlRaeder<4);
}
|
| Es gibt in Perl keine Parameterlisten beim Funktionsnamen. Die Parameter
werden innerhalb einer Funktion als Array @_ bereitgestellt. Die
können entweder als ganzes einzelnen Variablen zugewiesen werden:
sub funktion {
my ($param1,$param2,$param3) = @_;
...
}
oder mit dem shift-Operator der Reihe nach:sub funktion {
my $param1 = shift;
my $param2 = shift;
my $param3 = shift;
my $param4 = shift(@_); # ohne @_ wäre es identisch
...
}
Da die internen Variablen $_ und @_ defaultmäßig
für Funktionsaufrufe verwendet werden, sollten keine angegeben sein, kann man
bei shift das @_ weglassen. |
| Lokale Variablen in Funktionen kennt Perl von Haus aus nicht.
Generell sind alle Variablen (innerhalb eines Package) global. Es gibt zwei
Konstrukte, lokale Variablen zu definieren, die um umgebenen Hauptprogramm
nicht einsehbar sind:
my $frischeVariable = 4711;
oder
local $lokaleBezeichnung = "08-15";
my legt echte lokale Variablen an, die nur innerhalb eines Blocks
{...} gültig sind und auf die auch nur innerhalb diesem zugegriffen
werden kann. local selbst repräsentiert lediglich einen Wert
(legt somit keine neue Variable an) innerhalb eines Blocks {...}
und in von darin aufgerufenen Unterprogrammen. Seitens der perl-Entwickler
wird jedoch grundsätzlich empfohlen, my zu verwenden. |
| Rückgabewerte werden mit return angegeben. Gibt es kein return ,
wird das Ergebnis des zuletzt ausgeführten Ausdrucks zurückgegeben. |
| Der Aufruf einer Funktion aus einem Package oder einer anderen oder gar
selben Funktion heraus, entspricht dem Verfahren anderer Sprachen:
$erg = meineFunktionVergleicht(1,2);
oder besser mit Prefix & :
$erg = &meineFunktionVergleicht(1,2);
& liefert nicht die Referenz oder Zeiger auf ein Element! |
Programmabbruch
Zum Abbrechen des Programms wegen eines schweren Fehlers gibt es
die Funktion die() . Diese erwartet einen String, der als
Fehlermeldung ausgegeben wird, bevor sich das Programm gnadenlos
beendet.
Wichtig hierbei ist das letzte Zeichen des Strings: Steht am Ende
des String ein Newline '\n ', werden Zeilennummern samt
Perl-Fehlertext nicht ausgegeben. Fehlt es, dann erscheint erst die
eigene Fehlermeldung und daran angehängt ein Text der Art at
___ line __ .
Daneben gibt es auch den normalen exit() -Aufruf, der
jedoch nichts weiter ausgibt (setzt nur einen numerischen
Rückgabewert, wenn angegeben).
Zeilenweises Einlesen aus einer Datei
open(IN,"einzulesendeDatei.dat") or die "Öffnen fehlgeschlagen: $!\n";
while(<IN>) {
chomp; # Newline entfernen, $_ enthält nun die Zeile ohne Newline
print $_; # gib Zeile ohne Newline auf Screen aus
}
close(IN);
Filehandles sind einfache Literale ohne Kennzeichnung wie
$ bei Arrays. Der erste Parameter des
open() -Aufrufs legt eins an. Der
<> -Operator liest einen "Record" ein.
Standardmäßig liest er eine Zeile, kann aber über Flags geändert
werden, daß er z.B. die ganze Datei am Stück einliest oder byteweise
in Blöcken.
$! ist übrigens eine interne Statusvariable, die den
letzten I/O-Error beinhaltet. Sollte open()
fehlschlagen, steht dort warum.
EInlesen eines Verzeichnisses
Ähnlich dem Dateieinlesen gibt es eigene
Methoden zum Einlesen von Verzeichnissen:
$verz = 'C:\temp'
opendir(DIR,$verz) or die "Verzeichnis nicht gefunden: $!\n";
@entries = readdir(DIR);
closedir(DIR);
Hiermit werden alle Einträge des Verzeichnisses in @entries
eingelesen. Analog dazu kann man auch einzeln Einträge lesen:
opendir(DIR,$verz) or die "Verzeichnis nicht gefunden: $!\n";
@entries=();
while ($entry=readdir(DIR)) {
push @entries,$entry;
}
closedir(DIR);
@entries enthält auch die Einträge
". " (aktuelles Verzeichnis) und
".. " (übergeordnetes Verzeichnis). Um diese
außen vor zu lassen, grep() t man sie weg:
@entries = grep(!/^\.{1,2}$/,@entries);
oder
@entries = grep(!/^(\.|\.\.)$/,@entries);
oder als Block {...}
@entries = grep { !/^(\.|\.\.)$/ } @entries;
(damit wird von rechts nach links jeweils ein Arrayelement
durchgereicht und verarbeitet)
oder gleich beim Einlesen:
@entries = grep { !/^(\.|\.\.)$/ } readdir(DIR);
Da den @entries das Verzeichnis fehlt, kann man es sich (recht
einfach gemacht) anhängen:
@entries = map { $verz."\\".$_ } grep { !/^(\.|\.\.)$/ } readdir(DIR);
Möchte man nur Dateien haben, muß grep() auf "Datei" prüfen:
@files = grep { -f $_ } map { $verz."\\".$_ } readdir(DIR);
Wichtig hierbei ist die Reihenfolge: Steht grep() nach
map() , dann fehlt dem "-f" Operator die
Verzeichnisinformation, um korrekt auf eine Datei zu prüfen.
". " und ".. "
brauchen nicht geprüft werden, da diese Verzeichnisse sind und dabei
sowieso rausfallen.
Die Art und Weise, komplette Dateipfadangaben zu erstellen, ist
unsicher, daher gibt es das Package
File::Spec::Functions mit nützlichen Funktionen:
use File::Spec::Functions;
$fullPath = catfile("C:","windows\fonts","tahoma.ttf");
$fullPath2 = catfile("/var/tmp","messages.log");
$fullPath ist dann "C:\windows\fonts\tahoma.ttf"
$fullPath2 ist dann "\var\tmp\messages.log"
(wenn unter Win32 angewandt)
Sortieren von numerischen Arrays
Ein Aufruf der Form
@sortierteZahlen = sort @unsortierteZahlen;
reicht nicht aus, um korrekt numerisch zu sortieren, da Perl von
Haus aus generell Strings kennt (auch wenn sie für uns numerisch
erscheinen). Das Array (10,2,1) würde dann als
(1,10,2) sortiert.
sort() selbst kann jedoch eigene Vergleichsoperatoren
und -funktionen anwenden. Um numerisch zu sortieren reicht dies:
@sortierteZahlen = sort { $a <=> $b } @unsortierteZahlen;
Der Operator <=> betrachtet seine beiden
Operanden als Zahlen und vergleicht so. Der Aufruf
@sortierteZahlen = sort { $a cmp $b } @unsortierteZahlen;
ist demnach identisch mit
@sortierteZahlen = sort(@unsortierteZahlen);
Die Parameter $a und $b im
sort{} -Block sind vorgegeben, damit sort()
diese für den Vergleich belegen kann.
Als Funktion liese sich das so lösen:
sub numCompare {
my $a=shift;
my $b=shift;
return $a - $b;
}
@sortierteZahlen = sort { &numCompare($a,$b); } @unsortierteZahlen;
@absteigendSortierteZahlen = sort { &numCompare($b,$a); } @unsortierteZahlen;
Um aufsteigend und absteigend zu ändern, vertauscht man lediglich
die beiden Parameter $a und $b innerhalb
des sort{} -Blocks.
Kommandozeilen-Argumente
Nach dem Programmstart sind im Array @ARGV die
Kommandozeilenparameter zu finden. Dieses kann direkt mit Indexen $ARGV[0],
... oder mit shift verarbeitet werden. Bei shift
ist zu beachten, daß shift bei wiederholtem Aufruf das Array
jeweils um das erste Element erleichtert bis es leer ist.
Der Name des Programms selbst ist in $0 (Dollar Null :) zu
finden.
|