| Ein Array ( Liste, Vektor ) fasst mehrere Variable unter einem gemeinsamen Namen zusammen. Perl bietet nicht nur klassische indizierte Arrays sondern auch anonyme Listen, assoziative Arrays (Hashes), darüber hinaus leistungsfähige Array-Funktionen. |
Auf dieser Seite finden sie eine Zusammenstellung von Themen zur Arbeit mit Listen,
Arrays und Hashes in Perl. Damit sollen bestehende Referenzen und Tutorials ergänzt werden. |
Perl
|
Scripts für CGI und Systemverwaltung |
| Arrays & Hashes | Schlüssel, indizierte Arrays, assoziative Hashes, Speicher |
| Definition | Erzeugen & Löschen von Arrays und Hashes, Initialisierung mit Daten |
| Eigenschaften | von Arrays und Hashes |
| Lesen & Schreiben | Zugriff auf Elemente und Slices von Arrays und Hashes |
| Manipulation | Einfügen & Löschen von Elementen, Operationen mit allen Elementen, etc |
| Schleifen | Verarbeitung von Arrays und Hashes in Schleifen (loops) |
| Sortieren | Sortieren und Mischen von Arrays |
| Adressen |
Arbeit mit Adressen (References, Pointers): Mehrdimensionale Arrays und Hashes, Übergabe von Arrays und Hashes an Unterprogramme |
| String | Umwandlung strukturierter Strings in Arrays und umgekehrt |
| Datenspeicher | Arrays als Stapel oder Warteschlange |
| Hash-Sperre | Modul Hash bietet Werkzeug für mehr Sicherheit |
| Vordefiniert | Vordefinierte Arrays enthalten Umgebungs-Daten |
| Hashing | Hashing-Funktionen zur Berechnung interner Hash-Codes |
| Perl-Module | Weitere Funktionen für Arrays und Hashes |
| Verwandte Themen | Arrays in Javascript, PHP, VBA |
Anonyme Listen, indizierte Arrays und assoziative Hashes |
|
ListenPerl bietet die Möglichkeit, Variable und Daten zu einfachen anonymen Listen zusammenzufassen, sozusagen eine Vorstufe zu Arrays.Die Elemente werden in () gestellt und durch Beistriche getrennt.
Deklaration: Das erste Beispiel deklariert die
Variablen $i, $j
und $kDie Liste hat keine andere Funktion als die Variablen zusammenzufassen und mit Anweisung my zu deklarieren. Zuweisung von Werten: Danach werden 3 Werte (Zahlen-Liste der rechten Seite) an 3 Variable (Variablen-Liste der linken Seite) zugewiesen. Anschließend gilt $i=11; $j=22; und $k=33; Deklaration von Arrays und Hashes: Das Beispiel deklariert zusätzlich zu den bestehenden Variablen eine weitere einfache (skalare) Variable $x, ein ganzzahlig indiziertes Array @y und ein assoziatives Hash %z. Initialisierung: Hier wird eine Liste zur Initialisierung der Elemente eines Arrays verwendet. Dabei kann oft der Operator .. eingesetzt werden: Damit werden Listen aufeinander folgender Zahlen oder Strings (!) erzeugt. Die Liste kann auch undefinierte (undef) Elemente oder leere Strings enthalten. Mehrere aufeinander folgende Trennzeichen werden ignoriert, d.h. erzeugen keine undefinierten Elemente. Arrays in Listen: Ein Array @z wird mit einer Liste initialisiert, die selbst ein Array enthält. Dabei werden alle Elemente der Liste expandiert, d.h. Array @y2 enthält die Zahl 1000, danach alle Zahlen aus Array @y, zuletzt die Zahl 1999. |
# Anwendung anonymer Listen in Perl:
my ($i,$j,$k);
# Deklaration von Variablen # Zuweisung von Werten an Variable # Deklarationen # Initialisierung eines Arrays # Operator 10..12 erzeugt 10,11,12 @y = ('a1'..'a3','xa'..'xc'); @y = (1,undef,,'a',''); # Arrays werden aufgelöst: |
Arrayssind Listen, deren Elemente unter einem gemeinsamen Variablen-Namen adressierbar sind. Zur Unterscheidung der einzelnen Elemente dient eine ganze Zahl, der Schlüssel, hier meist als Index bezeichnet.Die Namen von Perl-Arrays beginnen mit @. Der Name eines einzelnen Array-Elements beginnt mit $, da es sich dabei um eines skalare Variable handelt. Der ganzzahlige Index wird in [] gesetzt und beginnt ohne sonstige Vereinbarung mit der Zahl 0. Deklaration: Im Beispiel werden drei Arrays @ara, @arb und @arc deklariert. Zu diesem Zeitpunkt existieren die Arrays und sind verwendbar, haben jedoch noch keine Elemente. Initialisierung: Danach werden dem Array @ara mit einer Liste (siehe oben) Werte zugewiesen, im Beispiel die Zahlen $a[0]=10; bis $a[10]=20; insgesamt 11 Elemente. Wenn in der Zuweisungs-Liste ein Array enthalten ist, dann werden dessen Elemente an der entsprechenden Stelle eingereiht: Array @arb enthält 13 Elemente, und zwar $arb[0]=1; danach die 11 Elemente aus @ara und zuletzt $arb[12]=99; Adressierung: Am Element $ara[3] wird die Adressierung eines einzelnen Elements demonstriert. Kopie: In Array @arc wird eine komplette Kopie von @ara erzeugt, d.h. spätere Änderungen von @arc lassen @ara unverändert. Index ab 0: Zuletzt wird demonstriert, dass jedes Array mit Index [0] beginnt: Selbst wenn unmittelbar nach Deklaration von Array @arx nur das Element [2] geschrieben wird, hat das Array bereits 3 Elemente mit Indices [0] bis [2], von denen allerdings die ersten beiden nicht definiert sind. |
# Array-Deklaration
my (@ara,@arb,@arc);
# Einfache Initialisierung @ara = (10..20); @arb = (1,@ara,99); # Adressierung von Array-Elementen $x = $ara[2] + $ara[3]; # Kopie eines Arrays # Index immer ab [0]: $arx[2]=22; # @arx=(undef,undef,22);
|
Hashessind ungeordnete Listen, deren Elemente unter einem gemeinsamen Variablen-Namen adressierbar sind. Zur Unterscheidung der einzelnen Elemente dient ein Text-Schlüssel (key). In anderen Programmiersprachen werden Hashes auch als assoziative Arrays bezeichnet.Die Namen von Perl-Hashes beginnen mit %. Der Name eines einzelnen Hash-Elements beginnt mit $, da es sich dabei um eine skalare Variable oder um einen Pointer handelt. Der Index wird in geschwungene {} Klammern gesetzt. Der Operator => bewirkt die Zuordnung von Schlüssel und Wert. Jedes Hash-Element speichert zuerst den Schlüssel (key), danach den Wert (value) als zusammengehörendes Daten-Paar (bucket). Die Bezeichnung 'Hash' stammt von den intern verwendeten Hasing-Funktionen. |
# Hash-Deklaration
my (%ha,%hb);
# Einfache Initialisierung %ha = ('r',255,'g',128,'b',0); # Adressierung von Hash-Elementen $gry = ($ha{'r'}+$ha{'g'}+$ha{'b'})/3;
# Beispiel
%ENV
(Umgebungs-Daten)
|
| Initialisierung: Das Hash %ha wird mit einer Liste (s.o.) gefüllt. Die Zuordnung von Schlüssel zu Wert erfolgt mit dem => Operator. Alternativ kann die Liste Paare von Werten enthalten, von denen das erste als Schlüssel, das zweite als Wert interpretiert wird. Das ist jedoch weniger übersichtlich und anfällig für Fehler. |
Die Reihenfolge der Hash-Elemente ist unbestimmt,
d.h. unabhängig von der Reihenfolge der Eingabe. Die tatsächliche Reihenfolge
wird durch den aus dem Schlüssel berechneten
Hash-Code bestimmt. Hashes sind daher prinzipiell ungeordnet, können aber geordnet bearbeitet werden (Sortierung). |
Definition, Initialisierung und Löschen von Arrays und Hashes |
|
|
Theoretisch können Perl-Variable einfach durch ihre Verwendung deklariert
werden. Es wird jedoch unbedingt empfohlen, Perl-Programme nur in
der strict-Variante zu verwenden.
Die Anweisung use strict; erzwingt eine
ausdrückliche Deklaration aller Variablen (Array, Hashes) vor der Verwendung.
Dadurch können viele Entwicklungs-Fehler frühzeitig erkannt und
beseitigt werden. Die Deklaration erfolgt mit der Anweisung my und Angabe einer Variablen oder einer Liste von Variablen. Solche Deklarations-Listen können in beliebiger Folge einfache (skalare) Variable, Arrays und Hashes enthalten. Es ist jedoch ratsam, die Deklarationen sinnvoll aufzuteilen und anzuzordnen. Deklarationen mit my können an jeder beliebigen Stelle im Programm erfolgen. Normalerweise werden sie am Beginn jedes Programm-Teils zusammengefasst. Es ist möglich, Variable im Laufe eines Programms mehrmals zu deklarieren. Dabei wird der vorherige Wert der Variablen gelöscht. |
# Deklaration
use strict;
# Zahlen
my($i,$j,@arr,@ars,%rgb);
# Strings
my($t,@vornamen,%pers);
# mit Initialisierung
my(@arn) = (0..100);my(@art) = ('a'..'z'); my(%p) = ('vn'=>'Anna','zn'=>'Reiter'); my(@arv) = qw(Anna Bert Christa); |
|
Mit einem Trick kann man Speicherplatz für ein Hash reservieren. Funktion keys gibt normalerweise ein Array aller Schlüssel eines Hash zurück. Wenn diese Funktion auf einen skalaren Wert gesetzt wird, dann reserviert sie die nächsthöhere 2er-Potenz an Speicherplätzen. |
keys(%rgb) = 10;
# reserviert 16 buckets
|
Zeilenweise InitialisierungSo kann man Daten zeilenweise in ein Array eingeben. Das eignet sich für die Automatisierung: Programm-Texte dieser Art kann man mit vielen Programmen bzw. mit jeder Programmiersprache erzeugen, und damit Daten an ein Perl Script-Programm übergeben.Alternativ kann man zur Adressierung den höchsten vorhandenen Index $# verwenden (s. Array-Eigenschaften) Funktion push hängt ein oder mehrere Elemente am Ende eines Arrays an. |
my($i,@arb);
$i = 0; $arb[$i++] = 12; $arb[$i++] = 23; $arb[$i++] = 345; # alternativ
$arb[$#arb+1] = 456;push(@arb,67); push(@arb,78,89,90); |
LöschenFunktion delete: löscht einzelne Elemente oder Slices (mehrere Elemente) aus Arrays oder Hashes und gibt die gelöschten Elemente zurück.Funktion splice kann Elemente oder Slices löschen, einfügen oder ersetzen (s. Array-Manipulation). Leere Liste: Das Löschen aller Elemente erfolgt durch Zuweisung einer leeren Liste. Dabei bleibt ein leeres Array oder Hash erhalten. Funktion undef: Zum raschen und vollständigen Löschen eines Array oder Hash inklusiver aller Elemente wird die Funktion undef verwendet. Das Löschen großer Arrays kann notwendig sein, um den belegten Speicherplatz freizugeben. |
# Löschen von Elementen oder Slices
$d = delete $arr[12];@ad = delete $arr[12,13]; @ad = delete $arr[12..15]; $d = delete %ha{'Walter'} @ad = delete %ha{'r','y'} # Löschen aller Elemente
@arr = ();%p=(); # Löschen von Arrays oder Hashes
undef @arr;undef %p; |
Lesen und Schreiben von Array- und Hash-Elementen und Slices |
|
| Jedes einzelne Element einer Liste, eines Arrays oder Hashes verhält sich wie eine einzelne (skalare) Variable. Daher beginnt der Name eines Elements mit $, gefolgt vom Namen des Arrays oder Hashes. | Danach wird zur Adressierung der Schlüssel (key) des gewünschten Elements angegeben. Perl verwendet dabei unterschiedliche (!) Syntax für indizierte Arrays und assoziative Hashes. |
Array-Elemente► Der Index eines Array-Elements wird in [] gesetzt und kann durch eine Zahl oder durch eine Variable angegeben werden.► Das erste Element jedes Arrays hat den Index [0] (Dieser Index wird mit der ↓ vor-definierten globalen Variablen $[ festgelegt) ► Eine Besonderheit ist die Angabe negativer Indices: in diesem Fall werden die Elemente vom Ende des Array rückwärts gezählt. $ara[-2] bezeichnet daher das vorletzte Element dieses Arrays. |
@ara = (0..8);
# @ara=(0,1,2,3,4,5,6,7,8);
$ara[3] = 333;# @ara=(0,1,2,333,4,5,6,7,8);
$v = $ara[3];
# $v=333;
$i = 5;$v = $ara[$i] - $ara[2]; $z = $ara[$v]; # $v=3; $z=333;
$ara[-2] = 999;
# @ara=(0,1,2,333,4,5,6,999,8);
|
|
Text-(String)-Elemente
•
Der Variablen-Typ von Array-Elementen ist nicht festgelegt. Arrays können Zahlen
(Beispiel oben) und/oder Texte (Strings) enthalten, auch gemischt.• Die Werte von String-Elementen werden in 'einfache' Anführungszeichen (single quotes) eingeschlossen. • Funktion qw erlaubt eine besonders einfache Syntax ohne quotes: Die einzelnen Werte werden durch Leerzeichen getrennt. (Die ↓ vor-definierte globale Variable $" legt das Trennzeichen fest). • Bei Verwendung "doppelter" Anführungszeichen (double quotes) wird der Wert interpretiert, d.h. darin enthaltene Variable und maskierte Sonderzeichen werden vor der Zuweisung 'berechnet'. |
@arb = ('Zara','Walter','Vera');
@arb = qw(Zara Walter Vera); $t='Anna'; @arc = (123,$t,'Berta',"new\nline","x$tx");
# ergibt @arc = (123,'Anna','Berta','new'
# 'line','xAnnax') |
|
Ein Array kann Elemente enthalten, die selbst Arrays oder Hashes sind. Das ergibt → mehr-dimensionale Arrays (Details zum Thema Pointer). |
my @ar2dim = (123,$t,\@ara);
|
Hash-Elemente● Hashes enthalten Werte-Paare. Jedes Hash-Element besteht aus einem Paar (Schlüssel/Wert) (key/value).● Der Schlüssel (key) eines Hash-Elements wird in geschwungene {} Klammern gesetzt und kann durch einen Text (String) oder durch eine Variable angegeben werden. ● Die Zuweisung von Werten erfolgt mit der Syntax Schlüssel=>Wert Alternativ kann man Schlüssel und Werte paarweise angeben, das ist jedoch anfällige gegen Programmier-Fehler. • Der Zugriff auf ein nicht vorhandenes Hash-Element ergibt den Wert undef, der sich bei der Ausgabe (print) wie ein leerer String '' verhält. |
# Initialisierung von Hashes
%hb = ('r'=>32,'g'=>43,'b'=>54);%hb = ('r',32,'g',43,'b',54); # Lesen und Schreiben von Elementen
$v = $hb{'r'};
# $v=32;
$hb{'r'} = 123;$hb{'yellow'} = 99; # neues Element $k = 'yellow'; $v = $hb{$k}; # $v=99;
$v = $hb{'gibznicht'};
# $v=undef;
|
Slicessind Teile von Arrays oder Hashes.Perl bietet eine elegante Syntax, um ausgewählte Teile eines Arrays zu adressieren. • Das erste Beispiel übergibt alle Elemente mit den Indices der Liste in [] an das Slice-Array @s (negative Indices werden vom Array-Ende rückwärts gezählt). • Das zweite Beispiel adressiert einen ganzen Bereich von Indices (hier [3..6] ) und wirkt daher ähnlich wie eine Schleife. • Diese Methode wird u.a. zum Tausch von Array-Elementen (Sortieren) verwendet. • Danach wird die gleiche Methode für ein Hash gezeigt. Sie wird hier verwendet, um eine Liste von Werten an mehrere Elemente des Hash %c zu übergeben. ♣ Beachten sie die Syntax: Die Namen von Slices werden sowohl für Arrays als auch für Hashes mit dem Zeichen @ angegeben, die Indices/Keys jedoch wie üblich für Arrays in [], für Hashes in {} |
@ara = (100..120);
# Auswahl von Array-Elementen
@s = @ara[3,6,-1];
# @s = (103,106,120);
@s = @ara[3..6];
# @s = (103,104,105,106);
# Vertauschung von 2 Elementen: # Hash: # %hc = ('r'=>123,'g'=>135,'b'=>246);
|
|
Schieberegister
Das Beispiel verschiebt alle Elemente des Arrays @sr um 1 Position
nach 'links'. Die Syntax wird zuerst speziell für dieses Beispiel (6 Elemente)
angegeben, danach allgemein für Arrays beliebiger Länge.
Der Index $#sr bezeichnet stets das letzte Array-Element.Bei einem zyklischen (Rotate)-Register wird der Kreis geschlossen: Der Wert des ersten Elements $sr{0] wird in das letzte Element $sr[$#sr] eingetragen. Bei Ausführung in einer Schleife werden alle Elemente des Arrays rotiert. |
@sr=(100..105);
print "sr=@sr\n"; # Ausgabe: sr=100 101 102 103 104 105
@sr[0..4] = @sr[1..5];@sr[0..$#sr-1] = @sr[1..$#sr];
# Ausgabe: sr=101 102 103 104 105 105
foreach (@ar){
# Zyklisches Schieberegister
@sr[0..$#sr-1,$#sr]=@sr[1..$#sr,0];
}
print "sr=@sr\n";
# Ausgabe:
# sr=100 101 102 103 104 105 # sr=101 102 103 104 105 100 # sr=102 103 104 105 100 101 # usw. |
FunktionenZahlreiche Perl-Funktionen liefern als Ergebnis ein Array oder Hash. Man kann das Ergebnis an eine Liste einfacher (skalerer) Variablen übergeben oder an ein Array bzw. Hash. Bei ungleicher Anzahl der Elemente werden soviele Elemente zugewiesen wie möglich.Beispiel: Funktion gmtime liefert die Komponenten von Datum und Weltzeit UTC als Array von 9 Elementen. Alle Daten werden an das Array @dta übergeben, jedoch nur die ersten 3 Elemente an die Variablen $ss, $mi und $hh Auch anonyme Listen können indiziert werden: Im Beispiel werden alle 9 Elemente an eine Liste in () übergeben, davon wird ein Slice [3..5] oder nur ein Element [3] ausgewählt und an die skalare Variable $dd überwiesen. Alternativ werden die ersten 3 Elemente der Liste mit undef verworfen und das nächste Element für $dd verwendet. |
my($yy,$mo,$dd,$hh,$mi,$ss,@dtar);
# Zuweisung aller 9 Elementen an Array @dta # Zuweisung nur der ersten 3 Elemente # Zuweisung nur der Elemente 3..5
($dd,$mo,$yy) = (gmtime(time()))[3..5];
# Zuweisung nur von Element [3]
$dd = (gmtime(time()))[3];(undef,undef,undef,$dd) = gmtime(time()); |
Unterprogrammeerhalten in Perl ihre Argumente im Array _@Normalerweise werden die übergebenen Argumente gleich zu Beginn an eine anonyme Liste von lokalen Variablen übergeben. Wenn sich in dieser Liste ein lokales Array befindet, dann saugt es alle folgenden Elemente von @_ auf ! Das kann schwer auffindbare Fehler ergeben. Im Beispiel ist subtest1 sauber programmiert, subtest2 dagegen gefährlich. ● Die Liste der lokalen Variablen darf daher nur ein einziges Array oder Hash enthalten, und zwar nur als letztes Element ! ● Verwenden sie zur Übergabe von Arrays besser nur deren Adressen (nächstes Kapitel) ! |
subtest1('a','b','c',10,20,30);
subtest2('a','b','c',10,20,30); sub subtest1 {
my($v1,$v2,$v3,@a1)=@_;
}
# $v1='a'; $v2='b'; $v3='c';
# @a1 = (10,20,30); sub subtest2 {
my(@a1,$v1,$v2,$v3)=@_;
}
# @a1 = ('a','b','c',10,20,30);
# Variable $v1 . . $v3 sind leer ! |
Adressen (references, pointer)Perl bietet die Möglichkeit nicht nur mit Variablen, sondern auch mit deren Adressen zu arbeiten.♦ Details zu Adressen von Arrays und Hashes |
Die Übergabe von Adressen an Stelle der Arrays bietet wichtige Vorteile: • Beliebig viele Arrays können an subs übergeben werden. • Die Reihenfolge der Argumente ist beliebig. |
Adressen von Arrays und Hashes |
|
Perl bietet die Möglichkeit nicht nur mit Variablen, sondern auch mit deren
Adressen zu arbeiten. Das Beispiel demonstriert die verwendete Syntax mit einem
Array.Variable → AdresseEin \ backslash-Zeichen vor dem Namen einer Variablen erzeugt die Adresse der Variablen - auch bei Arrays und Hashes.Adresse → VariableGeschwungene {} Klammern um eine skalare Variable bewirken ihre Interpretation als Adresse.Beispiel rechts: Hier wird die Adresse von Array $ara an die Variable $aradr übergeben. Danach wird demonstriert, wie man wahlweise den Variablen-Namen @ara oder die Adresse $aradr verwenden kann. Die Syntax-Variante mit dem -> Operator funktioniert ähnlich wie in der Programmiersprache C++. |
my($aradr,@ara,$v);
@ara = (3..6); $aradr = \@ara; # ist äquivalent zu
$aradr = [3,4,5,6];
# @ara ist äquivalent zu @{$aradr}
$v = $ara[2];# Auswahl von Elementen: $v = ${$aradr}[2]; $v = $aradr->[2]; # Array-Länge: $arlen = @{$aradr}; |
|
Verwendung von Adressen (references, pointer) mit Hashes: Das Beispiel funktioniert sinngemäß genauso wie bei den Arrays gezeigt. |
my($hadr,%ha,$v);
%ha = ('r'=>12,'g'=>23,'b'=>34); $hadr = \%ha; # ist äquivalent zu
$hadr = {'r'=>12,'g'=>23,'b'=>34};
# %ha ist nun äquivalent zu %{$hadr}
$v = $ha{'g'};# Auswahl von Elementen: $v = ${$hadr}{'g'}; $v = $hadr->{'g'}; |
Mehrdimensionale Arrays und HashesMit der gezeigten Adressen-Logik werden in Perl komplexe (mehrdimensionale) Strukturen aufgebaut:Ein Array oder Hash kann als Elemente nicht Daten sondern auch die Adressen weiterer Arrays (Pointer) enthalten. Derartige Sub-Arrays können selbst wieder Daten oder weitere Pointer enthalten. Das Beispiel zeigt den Aufbau eines einfachen 2dimensionalen Arrays, zuerst in einzelnen Schritten: Jede Zeile wird als eigenes Array angelegt, aus den Adressen der beiden Zeilen wird das 2-dimensionale Array erstellt. Danach wird das gleiche Beispiel in verkürzter Syntax gezeigt. Zuletzt wird der Zugriff auf einzelne Elemente mehrdimensionaler Arrays demonstriert. Die detaillierte Variante zeigt, dass mit Index [0] die erste der beiden Adressen von Array @a2d ausgewählt wird. Danach wird (-> Operator) jenes Array aufgesucht, auf welches diese Adresse zeigt. Davon wird mit Index [1] das Element mit dem Wert 12 ausgewählt. Üblich ist die verkürzte Schreibweise, in welcher alle Pfeil -> Operatoren zwischen mehreren Indices wegfallen (letzte Zeile). |
# 2dim Array, 2 Zeilen mit je 3 Spalten
my(@z1,@z2,@a2d,$adrz1,$adrz2);
# Aufbau in Einzel-Schritten
@z1 = (11,12,13); # Zeile 1$adrz1 = \@z1; @z2 = (21,22,23); # Zeile 2 $adrz2 = \@z2; @a2d = ($adrz1,$adrz2); # ist äquivalen zu $adrz2=[21,22,23]; @a2d = ($adrz1,$adrz2); # ist äquivalen zu # Adressierung von Zeile 1, Spalte 2, Wert 12 $v = $a2d[0][1]; |
Adressen als Argumente von Unterprogrammen● Es wird davon abgeraten, Arrays oder Hashes als Argumente an Unterprogramme zu übergeben. Das kann zu schwer auffindbaren Fehlern führen.● Die Übergabe der Adressen (Referenzen, Pointer) funktioniert rasch und problemlos. ♦ Details zur Übergabe von Arrays und Hashes an Unterprogramme. |
my @ar = (98,76,54);
my @br = ('z','y','x'); # Empfehlenswert:
mysub(\@ar1,$x,\@ar2);
# Nicht empfehlenswert !
# mysub(@ar,$x,@br); |
Verarbeitung von Arrays & Hashes in Schleifen |
|
|
Array-Schleife mit Index
Eine Zähler-(for)-Schleife die häufigste Methode
zur Verarbeitung indizierter Arrays. Dabei wird der Schleifen-Zähler
(hier $i ) zugleich als Index zur Adressierung der
Array-Elemente verwendet.Im Beispiel wird ein Array @ara deklariert und mit den Zahlen 5 bis 10 gefüllt. Das ergibt 6 Elemente. Die Anzahl der Elemente wird durch Zuweisung der Array-Variablen an eine skalare Variable ($arlen) ermittelt, und die Schleife danach ausgelegt. Zur Demonstration wird jedes Array-Element ausgegeben. |
my(@ara,$i,$arlen);
@ara = (5..10); $arlen = @ara; # $arlen = 6;
for($i=0;$i<$arlen;$i++) {
print "ara[$i]=".$ara[$i]."\n";
}
|
|
Array-Schleife ohne Index
Eine foreach-Schleife erfasst automatisch alle Elemente
eines Arrays, ohne dass deren Anzahl bekannt sein muss. Dabei wird der Wert jedes
Array-Elements an die Schleifen-Variable (hier $v )
überwiesen.Zur Demonstration werden die Werte aller Array-Elemente in einer Zeile ausgegeben. Eine weitere Verarbeitung (Änderung) der Schleifen-Variablen ist möglich, hat jedoch keine Wirkung auf das Array. Wenn Array-Elemente geändert werden sollen, dann muss eine Array-Schleife mit Index verwendet werden. Vorsicht - innerhalb der Schleife darf kein Array-Element eingefügt oder gelöscht werden. |
my(@ara,$v,$arlen);
@ara = (5..10); foreach $v(@ara) { print "$v ";
}print "\n"; |
|
Hash-Schleife mit Schlüsseln und Werten
Das Beispiel zeigt die meist verwendete Methode zur Verarbeitung von Hashes.Funktion each gibt bei jedem Aufruf eine Liste aus (Schlüssel,Wert) eines Hash-Elements zurück. Bei wiederholter Ausführung werden alle Elemente eines Hash durchlaufen, nach dem Ende wird eine leere Liste zurückgegeben (danach wieder das erste Element). Das Beispiel zeigt die Anwendung mit einer while-Schleife. Nachteil ist die Verarbeitung in unbekannter Reihenfolge. Vorsicht - innerhalb der Schleife darf kein Hash-Element eingefügt oder gelöscht werden. Ausnahme: Das gerade bearbeitete Element kann sicher gelöscht werden (hier z.B. mit delete $ha{$k}; ) |
my(%ha,$k,$v);
%ha = ('r'=>123,'g'=>234,'b'=>345); while (($k,$v) = each %ha) { print "key=$k, value=$v\n";
}
|
|
Hash-Schleife mit (sortierten) Schlüsseln
Wenn eine bestimmte Reihenfolge der Verarbeitung erwünscht ist, dann wird
diese Methode verwendet. Funktion keys liefert ein Array
mit allen Schlüsseln eines Hashes. Im Beispiel werden die Schlüssel im
Array @ka isoliert, meist auch sortiert.Die folgende foreach-Schleife kopiert jeweils einen Schlüssel-String in die Variable $k Mit dem Schlüssel $k wird der Wert $v des Hash-Elements ermittelt und zur Demonstration angezeigt. |
my(%ha,@ka,$k,$v);
%ha=("r"=>123,"g"=>234,"b"=>345); # @ka = keys(%ha); # unsortiert
@ka = sort keys(%ha);foreach $k(@ka) {
$v = $ha{$k};
}
print "key=$k, value=$v\n"; |
|
Dieses Beispiel durchläuft die Schleife mit der doppelten (!) Anzahl der
Hash-Elemente. Dabei wird abwechselnd je ein Schlüssel und ein Wert ausgegeben. Das hat kaum praktische Bedeutung, zeigt aber, wie die Elemente intern gespeichert sind. |
my(%ha,$v);
%ha=('r'=>123,'g'=>234,'b'=>345); foreach $v(%ha) { print "$v \n";
}
|
Funktion mapführt einfache arithmetische oder Text-Operationen mit allen Elementen eines Arrays oder Hashes aus.♦ Details im Kapitel Array-Manipulation. |
my(@ara,@arb);
@ara = (0..5); # @ara=(0,1,2,3,4,5);
@arb = map {$_ * $_} @ara;
# @arb=(0,1,4,9,16,25);
|
Funktion grepwendet ein Filter aus einem Regulären Ausdruck auf alle Elemente eines Arrays an. Viele Möglichkeiten für Arrays von Strings.♦ Details in den Kapiteln Array-Manipulation und Reguläre Ausdrücke. |
my(@ara,@arb);
@ara = qw(nur $mit Dollar); # @ara=('nur','$mit','Dollar');
@arb = grep {/^$/} @ara;
# @arb=('$mit');
|
Arrays und Unterprogramme (subs) |
|
Arrays in main sind global● Alle Variablen, die im "Hauptprogramm" (main) deklariert wurden, sind global. Sie stehen in allen subs zum Lesen und Schreiben zur Verfügung.● Das gilt nur für main - Wenn ein Array innerhalb eines sub deklariert wurde, dann ist es nicht global ! Im Beispiel wird ein Array @ar in main deklariert und mit ganzen Zahlen 0..10 gefüllt. Im Unterprogramm s1 wird das Element $ar[1] geändert. Die Änderung wirkt sich global aus: Die beiden print-Befehle in main ergeben daher zuerst die Zahl 1, danach 111. Das Array wird weder von main an das Sub übergeben, noch vom Sub zurückgegeben ! |
my(@ar)=(0..10);
Ausgabe: 1,1,111
print $ar[1].','; s1(); print $ar[1]; sub s1 {
print $ar[1].',';
}
$ar[1]=111; |
|
Array als Argument übergeben
Man kann Arrays und Hashes als Argumente an ein sub übergeben.● In diesem Fall wird eine komplette Kopie des Arrays erzeugt und übergeben. ● Nur ein einziges Array oder Hash darf als Argument übergeben werden, und zwar nur als letztes Argument der Liste. - Andernfalls zieht das Array bei der Verarbeitung im sub alle nachfolgenden Argumente an sich. ● Im sub kann man alle Daten der Kopie lesen und schreiben, Änderungen wirken zwar lokal (innerhalb des subs) jedoch nicht im Original-Array des aufrufenden Programms. ● An Stelle dieser Variante wird empfohlen, besser die Adressen als Argumente zu übergeben (nächster Absatz). |
my(@ar)=(0..10);
Ausgabe: 2,2,2
print $ar[2].','; s2(@ar); print $ar[2]; sub s2 {
my(@sar)=@_;
}
print $sar[2].','; $sar[2]=222; |
Array-Adresse als Argument übergeben● Man kann Adressen von Arrays und Hashes an ein sub übergeben. In diesem Fall hat das Sub vollen Zugriff auf das Original-Array.● Änderungen wirken global, d.h. sowohl im lokalen sub als auch im Array des aufrufenden Programms. Das gilt auch dann, wenn das aufrufende Programm selbst ein sub ist. ● (Nur) Auf diese Weise kann man beliebig viele Arrays an ein sub übergeben, und zwar in beliebiger Reihenfolge - Es werden lediglich skalare Variable übergeben, manche davon mit einer speziellen Bedeutung als Adressen. ♦ Details zur Verwendung von Adressen |
my(@ar)=(0..10);
Ausgabe: 3,3,333
print $ar[3].','; s3(\@ar); print $ar[3]; sub s3 {
my($sar)=@_;
}
# Länge:
my $alen=@{$sar};
# Element:
print ${$sar}[3].',';
# Änderung:
${$sar}[3]=333; |
Hash-Adresse als Argument übergeben:Die gleiche Methode kann auch zur Übergabe der Adressen von Hashes verwendet werden: Das Programm print_hash gibt eine Liste aller Hash-Elemente für jedes beliebige Hash aus. Die Elemente sind zur Vereinfachung nicht sortiert.● Wenn $sh die Adresse eines Hash %h ist, dann + wird das gesamte Hash statt mit %h mit %{$sh} angesprochen. + wird ein Element statt mit $h{'k'} mit ${$sh}{'k'} adressiert. Das Sub hat vollen Zugriff auf das Original Hash, kann daher auch alle Daten ändern. |
my %hcol;
$hcol{'r'} = 123; $hcol{'g'} = 234; $hcol{'b'} = 34; print_hash(\%hcol); sub print_hash {
my($sh) = @_;
}
my($k,$v,$i)=0; while (($k,$v)=each %{$sh}) { print '('.$i++.") $k = $v\n";
}
|
Array aus einem sub zurückgeben● Wenn ein Array oder Hash in einem Sub erzeugt wird, dann wird es einfach mit einer return-Anweisung an das aufrufende Programm übergeben.● Für wenige Elemente ist es oft bequemer, Listen an Stelle von Arrays zu verwenden. ● Bei der Rückgabe eines Array oder Hash werden allenfalls bereits vorhandene Elemente gelöscht, auch dann wenn das neue Array weniger Elemente enthält als das alte. Das Sub s4 erzeugt ein Array und gibt es zurück - wahlweise an ein Array oder an eine Liste von Variablen. Das Sub s5 erzeugt eine Liste, die im Beispiel an ein Array übergeben wird. |
my (@br)=s4();
my ($x,$y,$z)=s4(); my (@br)=s5(); sub s4 {
my(@sbr)=(41..43);
}return @sbr; sub s5 {
my $f=55;
}
return (54,$f,56); |
Texte und Arrays |
|
| Die Funktionen join und split dienen zur Umwandlung zwischen Arrays und systematisch strukturierten Strings, z.B. von Datei-Pfaden oder Internet-Adressen. Alle modernen Programmiersprachen bieten diese Standard-Funktionen. |
Die Funktionen pack und unpack dienen
zur Codierung und Decodierung intern gespeicherter Daten. Funktion qw wird häufig zur Initialisierung von String-Arrays verwendet. |
Funktion joinverbindet die Elemente eines Arrays von Strings zu einem einzelnen 'strukturierten' String. An jeder Verbindungs-Stelle wird wahlweise ein Separator-String eingesetzt - Meist ein einzelnes Zeichen, z.B. '/' |
my(@par1) = ('home','dev','perl','test1.pl');
my($path1) = join('/',@pa1); # $path1 = 'home/dev/perl/test1.pl';
|
Funktion splitZerlegt einen systematisch strukturierten String in Elemente eines Arrays. Der String wird bei jedem Auftreten eines Separator-Strings zerschnitten, dabei wird der Separator selbst unterdrückt.Die Funktion verwendet als erstes Argument einen Regulären Ausdruck zur Definition des Separator-Strings. |
my($path2) = 'home/dev/perl/test2.pl';
my(@par2) = split(/\//,$path2);
# @par2 = ('home','dev','perl','test2.pl');
|
Funktion packErzeugt nach einer Vorschrift (template) eine Variable aus den Werten einer Liste. Die Funktion eignet sich u.a. dazu, Strings aus Listen von Zeichen-Codes zu erzeugen.♦ Details zur Funktion pack |
my $v = pack('c*',65..70);
# $v='ABCDEF';
|
Funktion unpackZerlegt nach einer Vorschrift (template) eine Variable zu den Elementen einer Liste. Die Funktion demonstriert hier die Zerlegung eines Strings in ein Array, welches für jedes Zeichen den Zeichen-Code enthält.Funktion unpack ist u.a. gut geeignet für binäre Daten. ♦ Details zur Funktion unpack |
my @ara = unpack('c*','Test');
# @ara=(84,101,115,116);
|
'Funktion' qwist eigentlich ein 'quote-like' Operator (quoted words), welcher einen String in eine Liste von Worten zerlegt. Als Wort-Trennzeichen dient das Leerzeichen. Der String wird ohne (!) quotes in () übergeben, allfällig darin enthaltene quotes werden wie jedes andere Zeichen verwendet..qw wird oft zur bequemen Übergabe von Strings an Listen verwendet, z.B. zur Initialisierung von Arrays. |
my(@ars) = qw(das ist,ein "Test");
# @ars=('das','ist,ein','\"Test\"');
|
Minimal-AusgabeJedes Array aus Zahlen und Texten lässt sich in dieser Primitiv-Version ausgeben. Die Methode ermöglicht keine Formatierung, ist aber zum Debuggen kleiner Arrays recht gut geeignet.Zwischen den Elementen wird je ein Trennzeichen eingefügt, das in der vordefinierten globalen Variablen $" (list-separator) enthalten ist. Standard ist ein Leerzeichen, das kann aber geändert werden. |
my @ara =(11,'x',22,'y');
print "ara = @ara\n"; # ara = 11 x 22 y
$" = '+';print "ara = @ara\n"; #ara = 11+x+22+y
|
Vordefinierte globale Perl-VariableEinige dieser zahlreichen Variablen haben Bedeutung fr Arrays und/oder Strings$[ Start Index - Standard=0 - Mit diesem Index werden die ersten Elemente aller Arrays bezeichnet. Nicht ändern ! $" List separator - Standard=Leerzeichen chr(32)=chr(0x20) $; Subscript separator - Standard=chr(28)=chr(0x1C) $/ Input record separator - Standard=chr(10)=chr(0x0A)=\n $, Output field separator $\ Output record separator ♦ Details auf der Seite Perl-Umgebung |
|
Sortieren von Arrays |
|
Funktion sort()sortiert ein Array. Ohne weitere Angaben wird alphabetisch (lexikalisch) sortiert - Die Elemente werden nach ihrem Zeichencode sortiert. Das ist für Strings meistens erwünscht und ausreichend.Zahlen werden wie Text-Ziffern behandelt - das ist meistens unerwünscht ! |
my(@ara,@arb);
@ara = ('A',2,'z','a',0,'a5','ab',undef,'z',12,'',' ','Z'); @arb = sort @ara; # @arb=(undef,'',0,12,2,'A','Z','a','a5','ab','z');
|
|
Numerische Sortierung
Um Zahlen zu sortieren, muss eine andere Sortier-Vorschrift befolgt werden.
Das erfolgt durch Angabe eines Blocks (Mini-Programm), hier
z.B. {$a <=> $b} für steigende
oder {$b <=> $a} für fallende Werte.
|
my(@ara,@arb);
@ara = (10,11,12,0,1,-3,-4,100,2,3,20,21); @arb = sort @ara;
# Standard = alphabetisch
@arb = sort {$a <=> $b} @ara;
# @arb=(-3,-4,0,1,10,100,11,12,2,20,21,3); # @arb=(-4,-3,0,1,2,3,10,11,12,20,21,100);
|
|
Sortier-Programm
Sortier-Funktionen arbeiten intern durch Vergleich von jeweils 2 Elementen.
Je nach Ergebnis werden dann die beiden Elemente vertauscht oder nicht.Der Vergleich kann in eine eigene Funktion ausgelagert werden. Vergleichs-Funktion
erhält keine Argumente. Die zu vergleichenden Werte werden in den vordefinierten
globalen Variablen $a und $b
übergeben. Das Ergebnis des Vergleichs muss true
oder false sein, als Rückgabe-Wert genügt das
Ergebnis der zuletzt ausgeführten Programmzeile.Das Ergebnis eines Vergleichs wird so bewertet: + Alle (auch negative) Zahlen außer 0 sind true, 0 ist false. + Alle Strings mit >=1 Zeichen sind true, leere Strings sind false. + Der Wert undef ist false. Die Regeln für die Vergleichs-Funktion enthalten noch weitere Details (Perl-Manual, Kapitel perlfunc | ) Rechts einige Beispiele für Sortier-Funktionen. Nur als Demo: mysort_0 ergibt immer 0, sortiert daher überhaupt nicht. mysort_1 ergibt immer 1, kehrt daher das Array um. |
my(@ara,@arb);
@ara = (); @arb = sort mysort_uc @ara; # @arb=();
# sort case-independent alphabetic
sub mysort_uc {
uc($a) cmp uc($b);
}
# sort numeric ascending
sub mysort_numa {
$a <=> $b;
}
# sort numeric descending
sub mysort_numd {
$b <=> $a;
}
# (no) sort - asis
sub mysort_0 {
my $z=0;
}
# reverse
sub mysort_1 {
my $z=1;
}
|
|
Sortier-Block
Da die meisten Vergleichs-Programme sehr klein sind, können sie auch als
Programm-Block in {} eingeschlossen werden.Die beiden sort-Befehle im Beispiel rechts sind daher äquivalent. |
my(@ara,@arb);
@ara = (10,11,12,0,1,-3,-4,100,2,3,20,21); @arb = sort mysort_numa @ara; @arb = sort {$a <=> $b} @ara; # @arb=(-4,-3,0,1,2,3,10,11,12,20,21,100);
|
Funktion reversekehrt die Reihenfolge der Elemente eines Arrays um. Das Ergebnis wird oft an das gleiche Array übergeben. |
my(@ara);
@ara = (3,'a',undef,0,'Z'); @ara = reverse @ara; # @ara=('Z',0,undef,'a',3);
|
|
Sortieren von Hashes
ist nicht sinnvoll, da die Reihenfolge der Hash-Elemente im internen Speicher
unbestimmt ist.Für die Verarbeitung werden jedoch häufig die Schlüssel in ein Array kopiert und sortiert. |
Die Sortierung des Schlüssel-Arrays kann nach allen Regeln der Array-Sortierung erfolgen. Da die Schlüssel Strings sind, genügt meist die alphabetische (lexikalische) Sortierung, d.h. mit Funktion sort ohne weitere Argumente. |
Array-Manipulation |
|
Funktion keysliefert ein Array aus allen Schlüsseln eines Hashes.Sie wird häufig verwendet, um in einer Schleife auf alle Elemente des Hash zuzugreifen, meist zusammen mit sort verwendet. |
my(@ara,%ha);
%ha = ('r'=>123,'g'=>234,'b'=>210); @ara = keys(%ha); # @ara=('r','g','b');
@ara = sort keys(%ha);
# @ara=('b','g','r');
|
Funktion valuesliefert ein Array aus allen Werten eines Hashes. |
my(@ara,%ha);
%ha = ('r'=>123,'g'=>234,'b'=>210); @ara = values(%ha); # @ara=(123,234,210);
|
'Funktion' qwist eigentlich ein 'quote-like' Operator (quoted words), welcher einen String in eine Liste von Worten zerlegt. Als Wort-Trennzeichen dient das Leerzeichen. Der String wird ohne (!) quotes in () übergeben, allfällig darin enthaltene quotes werden wie jedes andere Zeichen verwendet..qw wird oft zur bequemen Übergabe von Strings an Listen verwendet, z.B. zur Initialisierung von Arrays. |
my(@ars) = qw(das ist,ein "Test");
# @ars=('das','ist,ein','\"Test\"');
|
Funktion spliceDiese Funktion ist sehr flexibel und verschiedene Array-Operationen ausführen. Sie schneidet einen Teil aus einem Array und fügt an der gleichen Stelle ein anderes Array ein. Alle modernen Programmiersprachen bieten diese Standard-Funktion.Um Elemente aus einem Array @ara zu entfernen erhält die splice-Funktion 3 Argumente (@ara, $offset, $len) Aus dem Array @ara wird ab (inkl.) Element $ara[$offset] die Anzahl von $len Elementen entfernt. Die entfernten (!) Elemente werden von der Funktion splice zurückgegeben (hier an das Array @s ). Zum Löschen von Elementen oder Slices kann auch Funktion delete verwendet werden (s. Löschen von Arrays). |
Entfernen von Elementen mit splice
my(@ara,@s);
@ara=('a'..'f'); # @ara=('a','b','c','d','e','f');
@s = splice(@ara,3,2);
# @s=('d','e');
# @ara=('a','b','c','f'); |
|
Um neue Elemente einzufügen erhält die Funktion 4
Argumente (@ara, $offset, 0, @arb) In das Array @ara werden vor dem Element $ara[$offset] alle Elemente von Array @arb eingefügt. Zum Einfügen von Elementen am Anfang oder Ende können auch die Funktionen unshift und push verwendet werden (s. Datenspeicher). |
Einfügen von Elementen mit splice
my(@ara,@arb,@s);
@ara=('a'..'f'); @arb=('x','y'); # @ara=('a','b','c','d','e','f');
@s = splice(@ara,3,0,@arb);
# @s=();
# @ara=('a','b','c','x','y','d','e','f'); |
|
Um Elemente sowohl einzufügen als auch zu entfernen erhält die
Funktion 4 Argumente (@ara, $offset, $len, @arb). Aus dem Array @ara wird ab Element $ara[$offset] die Anzahl von $len Elementen entfernt. An der gleichen Position werden alle Elemente von Array @arb eingefügt. Die entfernten Elemente werden von der Funktion splice zurückgegeben (hier an das Array @s). |
Entfernen und Einfügen von Elementen mit splice
my(@ara,@arb,@s);
@ara=('a'..'f'); @arb=('x','y'); # @ara=('a','b','c','d','e','f');
@s = splice(@ara,3,2,@arb);
# @s=('d','e');
# @ara=('a','b','c','x','y','f'); |
|
Für negative Argumente gelten besondere Regeln: Wenn $offset<0 wird die Position vom Ende des Arrays gezählt. Beispiel: $offset=-1 bezeichnet das letzte Element (hier $ara[5]="f"), $offset=-2 bezeichnet das vorletzte Element (hier $ara[4]="e"). |
Entfernen von Elementen mit splice
my(@ara,@s);
@ara = ('a'..'f'); # @ara=('a','b','c','d','e','f');
@s = splice(@ara,-5,2);
# @s=('b','c');
# @ara=('a','d','e','f'); |
Funktion mapbietet eine elegante und effiziente Möglichkeit, um einfache Operationen an allen Elementen eines Arrays oder Hashes auszuführen.Der Programm-Block in {} enthält ein Mini-Programm, welches auf alle Elemente angewendet wird. Der Wert jedes Elements wird in der Variablen $_ übergeben, das Programm damit ausgeführt, das Ergebnis in das Element des Ziel-Arrays übertragen. Das 3. Beispiel erzeugt eine Zufallszahl für jedes Element, d.h. $_ muss nicht unbedingt verwendet werden. Vorsicht - $_ ist ein Alias für das bearbeitete Element, d.h. eine Änderung von $_ bewirkt eine Änderung des 'Original'-Array-Elements ! Das letzte Beispiel zeigt, wie ein Hash aufgebaut werden kann. Das Mini-Programm muss für jedes Hash-Element 2 Daten (Schlüssel, Wert) zurückgeben, die mit Beistrich , getrennt werden. Funktion map eignet sich ausgezeichnet für einfache Arithmetik oder Text-Manipulation. |
my(@ara,@arb,%ha);
@ara = (0..5); @arb = map {$_ * 2} @ara; # @arb=(0,2,4,6,8,10);
@arb = map {$_ * $_} @ara;# @arb=(0,1,4,9,16,25);
@arb = map { int(rand(100)) } @ara;# @arb=(38,59,73,3,31,53);
@arb = map {"x".$_} @ara;# @arb=('x0','x1','x2','x3','x4','x5');
map {$_=1} @ara; # Vorsicht !# @ara=(1,1,1,1,1,1);
@ara=(65..67);%ha = map {chr($_),$_} @ara; # %ha=('A'=>65,'B'=>66,'C'=>67);
|
Funktion grepbietet die Möglichkeit, ein Filter aus einem Regulären Ausdruck auf alle Elemente eines Arrays anzuwenden.Der Programm-Block in {} enthält einen Regulären Ausdruck. Nur bei einem Treffer wird das Element ausgegeben. Das zweite Beispiel zeigt die Umkehrung - Hier werden nur die nicht zutreffenden Array-Elemente ausgegeben. Das dritte Beispiel zeigt die gleichzeitige Anwendung einer Zeichen-Substitution (vorangestelltes s): jedes erste vorkommende Zeichen e wird durch x ersetzt. ♦ Details zu Regulären Ausdrücken. |
my(@ara,@arb);
@ara = qw(Das ist ein neuer Test); @arb = grep {/s/} @ara; # @arb=('Das','ist','Test');
@arb = grep {!/s/} @ara;# @arb=('ein','neuer');
@arb = grep {s/e/x/} @ara;# @arb=('xin','nxuer','Txst');
|
Vordefinierte globale Arrays |
|
| Einige Arrays sind in Perl vordefiniert und daher in jedem Programm erreichbar. | ♦ Details im Kapitel Perl-Umgebung |
Array @ARGV - für Konsolen-Programmeenthält die 'Commandline-Argumente', mit denen das Perl-Interpreter-Programm gestartet wurde. Bei Konsolen-Programmen ist es üblich, das erwünschte Verhalten in Form von Options, Switches usw. in der Befehls-Zeile an das Programm weiterzugeben. Diese Argumente sind nur für Perl Script-Programme interessant, die auf der Konsole gestartet wurden, das sind meist Programme zur Systemverwaltung. |
$na = $#ARGV + 1;
print "Anzahl Argumente = $na\n"; $i=0; foreach $a (@ARGV) {
print "ARGV[$i] = $a\n";
}
$i++; |
CGI-Argumente - für Dynamische WebseitenEin Perl-Script-Programm zur Erzeugung einer dynamischen Webseite wird als CGI aufgerufen. Die an das Programm zur Steuerung übergebenen Argumente befinden sich dann im QUERYSTRING, den man als Element des Globalen Hashes %ENV erhält.Dieser String ist systematisch aufgebaut und kann entweder mit spezialisierten Perl-Funktionen (Modul CGI) oder mit den Methoden der Text-Array-Schnittstelle verarbeitet werden, d.h. mit Funktion split. ♦ Details auf der CGI-Webseite oder im Kapitel zu Text-Array-Funktionen. |
my $qs = $ENV{'QUERYSTRING'}; |
Array @INCenthält die Such-Pfade für externe Module. Das Perl-Interpreter-Programm sucht in bestimmten Pfaden nach benötigten Komponenten (z.B. für require ). Die Liste der Pfade ist im Globalen Array @INC enthalten und kann durch entsprechende Befehle (push) ergänzt werden. |
$newpath = 'home/test/perl_module';
push(@INC,$newpath); |
| Hash %ENV enthält Daten zur Hardware und Software der Umgebung, in welcher Perl ausgeführt wird. Das Perl-Programm läuft am Webserver, daher werden dessen aktuelle Umgebungs-Daten ausgegeben: | |
Argumente (Parameter) von Unterprogrammen |
|
Das Array @_ist in Perl vor-definiert und dient zur Übergabe von Argumenten (Parametern) an Unter-Programme (Subs). Die Elemente dieses Arrays werden mit $_[$index] adressiert. Der ungewöhnliche Name soll Verwechslungen mit selbst definierten Arrays verhindern.Beispiel: Die Funktion my_add wird mit 2 Argumenten aufgerufen, welche sie addieren soll. In der Definition des Subs fehlt - im Gegensatz zu vielen anderen Programmiersprachen - die Liste der Argumente. Perl stellt es frei, ob und wie viele Argumente ein Sub übernimmt. Im Beispiel wird das erste Argument an die lokale Variable $x zugewiesen, das zweite an $y . |
$r = my_add(123,456);
print "r = $r \n"; # Ausgabe: r = 579
sub my_add {
my $x = $_[0]
}
my $y = $_[1] my $r = $x+$y; return $r; |
Typische Sub-SyntaxDiese alternative Variante ist der oben vorgestellten genau äquivalent. Sie wird in den meisten Perl-Subs verwendet:• Alle Elemente des Arrays @_ werden an eine anonyme Liste von lokalen Variablen zugewiesen. Das ist elegent, erfordert jedoch sowohl im aufrufenden (Haupt)-Programm als auch im Sub die Kenntnis und Beachtung der Argumente-Anzahl. ♣ Hinweis: Die → Übergabe von Arrays und Hashes an Unterprogramme erfordert besondere Maßnahmen. |
sub my_add {
my($x,$y)=@_;
}
my $r = $x+$y; return $r; |
Dynamische Anzahl von ArgumentenIn dieser 'intelligenten' Version kann das Sub jede beliebige Anzahl von Argumenten verarbeiten.Das Sub bestimmt die Anzahl der jeweils erhaltenen Argumente und stellt sein Verhalten darauf ein. Die Programm-Zeilen vor dem Sub demonstrieren die Anwendung mit einer variablen anzahl von Argumenten. • Der Ausdruck $#_ bezeichnet den letzten Index des Arrays $@_. Da das erste Element den Index [0] hat, ist die Anzahl der Elemente $nargs um +1 größer als der letzte Index. • Im Beispiel werden die Werte aller Argumente $_[$i] addiert und danach die Summe $s zurückgegeben. |
print my_add(123);
# Ausgabe: 123
print my_add(12,34,56)# Ausgabe: 102
sub my_add {
my $nargs = $#_+1;
}my ($s,$i)=(0,0); for($i=0;$i<$nargs;$i++) { $s+=$_[$i];
}return $s; |
| Das Sub lässt sich auch füMr eine dynamische Anzahl von Argumenten knapp formulieren. |
sub my_add{
my $s=0;
}
foreach my $v(@_) {$s+=$v;} return $s; |
Hashing-Funktion |
|
|
Die Bezeichnung 'Hash' stammt von
Hashing-Funktionen: Text-Schlüssel sind zwar sehr praxisfreundlich, ihre interne Verwaltung wäre jedoch langsam. Daher wird aus jedem Schlüssel-String eine ganze Zahl berechnet und intern als Index verwendet. Ganzzahlige Indices lassen sich sehr schnell verwalten. Es gibt zahlreiche verschiedene Hashing-Algorithmen (Rechen-Vorschriften) zur Berechnung von Hash-Zahlen aus Strings. Hashing-Umwandlungen sind asymmetrisch: Aus gleichen Texten werden immer die gleichen Hash-Codes berechnet. Die Umkehrung ist jedoch nicht vorgesehen, und auch nicht eindeutig möglich. Wegen dieser Eigenschaft werden Hash-Funktionen auch zur internen Codierung von Passworten verwendet: Selbst bei Kenntnis des Hash-Codes kann das Passwort daraus nicht berechnet werden. Hash-Codes sind nicht eindeutig, daher ergeben sich aus einer sehr großen Anzahl von Schlüsseln evtl. die gleichen Hash-Codes. Alle Programme, die Hash-Codes verwenden (natürlich auch Perl) verwenden eigene Maßnahmen zur Handhabung derartiger Kollisionen. Hinweis: Das % Zeichen im Sub my_hash dient als → Modulo-Operator, nicht als Prefix eines Hash-Namens ! ♦ Details zur Funktion unpack |
Beispiel für eine Hashing-Funktion zum Experimentieren:
# Anwendung:
$s = 'Test';$h = my_hash($s); print "my_hash($s) = $h\n"; # Hashing-Funktion
sub my_hash {
}
|
|