Perl-Array

Arrays, Listen und Hashes in Perl

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 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

Listen

Perl 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 $k
Die 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:
# Deklaration von Variablen
my ($i,$j,$k);

# Zuweisung von Werten an Variable
($i,$j,$k) = (11,22,33);

# Deklarationen
my ($x,@y,@y2,%z);

# Initialisierung eines Arrays
# Operator 10..12 erzeugt 10,11,12
@y = (1,2,10..12,99);
@y = ('a1'..'a3','xa'..'xc');
@y = (1,undef,,'a','');

# Arrays werden aufgelöst:
my @y2 = (1000,$y,1999);

Arrays

sind 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 = (111,222,333);
@ara = (10..20);
@arb = (1,@ara,99);

# Adressierung von Array-Elementen
$ara[3] = 123;
$x = $ara[2] + $ara[3];

# Kopie eines Arrays
@arc = @ara;

# Index immer ab [0]:
my @arx;
$arx[2]=22;
# @arx=(undef,undef,22);

Hashes

sind 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);
%ha = ('r',255,'g',128,'b',0);

# Adressierung von Hash-Elementen
$ha{'r'} = 64;
$gry = ($ha{'r'}+$ha{'g'}+$ha{'b'})/3;

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 Initialisierung

So 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öschen

Funktion 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;

Eigenschaften von Arrays und Hashes

Anzahl der Elemente eines Arrays

Erhält man durch Zuweisung des Arrays an eine einfache (skalare) Variable. Das ist äquivalent zur Verwendung der Funktion scalar
Das Beispiel erzeugt ein Array @ara und füllt die 6 Elemente $ara[0] bis $ara[5] mit den Zahlen 5 bis 10. Zuweisung der Array-Variablen an die skalare Variable $arlen ergibt den Zahlenwert 6.

my($arlen,@ara);
@ara = (5..10);
$arlen = scalar(@ara);
# oder einfach
$arlen = @ara;
# ergibt:
# $arlen = 6
Man kann diese Möglichkeit dazu verwenden, um in einer Schleife alle Elemente eines Arrays zu verarbeiten.
for($i=0; $i<@ara; $i++) {
print '@ara['.$i.']='.$ara{$i]."\n";
}

Anzahl der Elemente eines Hash

Dazu erzeugt man zuerst ein Array aus allen Schlüsseln (keys) eines Hash.
Danach bestimmt man (wie im Absatz oberhalb gezeigt) die Anzahl der Array-Elemente, die gleich groß ist wie die Anzahl der Hash-Elemente.

my($hlen, %ha, @hka);
%ha= ('r'=>12, 'g'=>23, 'b'=>34);
@hka = keys %ha;
$hlen = scalar(@hka);
undef @hka;
# oder kompakt
$hlen = scalar(keys %ha);
# ergibt:
# $hlen = 3
Wenn man ein Hash (wie bei Arrays üblich) direkt an eine skalare Variable zuweist, dann kann das unterschiedliche unterschiedliche Ergebnisse liefern:
Wenn das Hash leer ist, wird der Wert false zurückgegeben.
Wenn das Hash Elemente enthält, dann wird ein String der Form ub/ab zurückgegeben, wobei ub=used buckets und ab=allocated buckets bedeutet, d.h. der verwendete Speicherplatz. In einer logischen Verzweigung (if) wird der String wie true behandelt, daher kann man auf diese Weise feststellen, ob Hash-Elemente angelegt wurden.
Achtung: Die Anwendung der für Arrays verwendeten Syntax auf anonyme Listen ergibt nicht die Anzahl der Elemente, sondern das letzte Element der Liste !
$test = ('a','b','c');
# ergibt:
# $test = 'c'

Existenz von Elementen

Die Perl-Funktion exists prüft die Existenz von Array- oder Hash-Elementen.
Sie kann nicht die Existenz gewöhnlicher (skalarer) Variablen testen, ebenso die Existenz von Arrays oder Hashes, sondern ausschließlich die Existenz bestimmter Elemente vorhandener Arrays oder Hashes.
if(exists($ara[33])) {
#if(exists($hc{'r'})) {
print "exist = Y\n";
}
else {print "exist = N\n";}

Letztes Array-Element

Der letzte verwendete Index ist mit einer speziellen Syntax zugänglich: Vor den Namen des Arrays werden die Zeichen $# gestellt. Da ganzzahlig indizierte Arrays mit dem Element [0] beginnen, ist die Anzahl der Elemente um +1 größer als der letzte Index !
Für ein Hash lässt sich kein 'letztes Element' angeben, da die Reihenfolge seiner Elemente prinzipiell unbestimmt ist !
my ($arz, $anz, @ara);
@ara = (10..12); # 3 Elemente
$arz = $#ara;
$anz = $#ara+1;
# Ergibt:
# $arz = 2
# $anz = 3

Unterscheidung Pointer - Skalar

Komplexe strukturen werden in Perl meist durch mehrdimensionale Hashes dargestellt. Arrays und Hashes können als Elemente nicht nur einfache Variable (Skalare, z.B. eine Zahl oder einen Text) sondern weitere Arrays oder Hashes enthalten. Bei der Verarbeitung der Elemente muss man unterscheiden, ob das untersuchte Element ein Skalar oder ein Array/Hash ist.

Im Beispiel wird zunächst ein Test-Hash %hsh erzeugt:
Das Hash erhält 3 Elemente:
2 der Elemente sind Skalare, ein Element ist selbst ein Hash aus 2 Elementen.

Danach werden die Elemente von %hsh in einer Schleife verarbeitet. Mit Funktion ref wird zwischen Skalaren und Referenzen (Pointern) unterschieden. Die Funktion wird hier vereinfacht wie ein Operator verwendet.
# Erzeugung eines mehrdimensionalen Test-Hash:
$hsh{'abc'}=123;
$hsh{'xyz'}='Text';
%hsub=('vn'=>'Franz','zn'=>'Weber');
$hsh{'sub'}=\%hsub;

# Verarbeitung der Elemente:
while(($k1,$v1) = each %hsh) {
if(ref $v1) {
print "Element $k1 (Pointer) = $v1\n";
while(($k2,$v2) = each %$v1) {
print "Sub-Element $k1,$k2 = $v2\n";
}
}
else{
print "Element $k1 (Skalar) = $v1\n";
}
}

Unterscheidung Array - Hash

Die Funktion ref gibt den Typ des Arguments zurück.
Wenn das Argument ein Skalar ist, dann wird ein leerer Text zurückgegeben.
Wenn das Argument eine Refenz (Pointer) ist, dann wird ein Text (String) zurückgegeben, welcher den Typ beschreibt. Die wichtigsten Rückgabe-Werte sind ARRAY und HASH
Feststellung des Typs einer Referenz:
# Herstellung eines Pointers
$v = \@abc;
# $v = \%xyz;

# Analyse des Pointers
$test = ref($v)
print "v ist ein Pointer -> $test\n";
# Ausgabe:
# v ist ein Pointer -> ARRAY

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;

Slices

sind 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:
@ara[$i,$j] = @ara[$j,$i];


# Hash:
@hc{'r','g','b'}=(123,135,246);
# %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

# Zyklisches Schieberegister
foreach (@ar){
@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.

Funktionen

Zahlreiche 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
@dta = gmtime(time());

# Zuweisung nur der ersten 3 Elemente
($ss,$mi,$hh) = gmtime(time());
# 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());

Unterprogramme

erhalten 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 → Adresse

Ein \ backslash-Zeichen vor dem Namen einer Variablen erzeugt die Adresse der Variablen - auch bei Arrays und Hashes.

Adresse → Variable

Geschwungene {} 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}

# Auswahl von Elementen:
$v = $ara[2];
$v = ${$aradr}[2];
$v = $aradr->[2];

# Array-Länge:
$arlen = @ara;
$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}

# Auswahl von Elementen:
$v = $ha{'g'};
$v = ${$hadr}{'g'};
$v = $hadr->{'g'};

Mehrdimensionale Arrays und Hashes

Mit 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
$adrz1=[11,12,13];
$adrz2=[21,22,23];
@a2d = ($adrz1,$adrz2);

# ist äquivalen zu
@a2d = ( [11,12,13],[21,22,23] );


# Adressierung von Zeile 1, Spalte 2, Wert 12
$v = $a2d[0]->[1];
$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 map

fü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 grep

wendet 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);
print $ar[1].',';
s1();
print $ar[1];

sub s1 {
print $ar[1].',';
$ar[1]=111;
}
Ausgabe: 1,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.
Langsame Methode ! Vorsicht: Die Übergabe großer Arrays erfordert viel Rechenzeit !
An Stelle dieser Variante wird empfohlen, besser die Adressen als Argumente zu übergeben (nächster Absatz).
my(@ar)=(0..10);
print $ar[2].',';
s2(@ar);
print $ar[2];

sub s2 {
my(@sar)=@_;
print $sar[2].',';
$sar[2]=222;
}
Ausgabe: 2,2,2

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.
Schnell und allgemein anwendbar Diese Methode ist sparsam und schnell, und zwar sowohl zur Übergabe von Arrays an Subs als auch zur Rückgabe von Arrays aus subs !

Details zur Verwendung von Adressen
my(@ar)=(0..10);
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;
}
Ausgabe: 3,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 join

verbindet 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 split

Zerlegt 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 pack

Erzeugt 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 unpack

Zerlegt 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' qw

ist 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-Ausgabe

Jedes 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-Variable

Einige 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=(-3,-4,0,1,10,100,11,12,2,20,21,3);
@arb = sort {$a <=> $b} @ara;
# @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 reverse

kehrt 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 keys

liefert 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 values

liefert 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' qw

ist 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 splice

Diese 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 map

bietet 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 grep

bietet 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-Programme

enthä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 Webseiten

Ein 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 @INC

enthä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:

Spezielle Perl-Variable

Einige globale Variable sind in Perl vor-definiert und haben eine besondere Bedeutung. Damit sie nicht irrtümlich durch eigene Variable überschrieben werden, haben sie exotische Namen.

Start-Index

Das ist jene ganze Zahl, mit welcher das erste Element jedes Arrays bezeichnet wird. In allen modernen Programmiersprachen wird dafür die Zahl 0 verwendet.
Tipp: Sie sollten diesen Wert nach Möglichkeit nicht ändern.
print 'start index = '.$[.";
print '= ASCII'.ord($[)."\n";
# Ausgabe:
# Start Index = 0 = ASCII 48

List Separator

gibt jenes Zeichen an, welches bei der unformatierten Ausgabe von Listen als Trennzeichen zwischen die einzelnen Elemente gesetzt wird.
Perl verwendet dafür normalerweise das Leerzeichen (Space, Blank).
print 'list separator = '.$".";
print '= ASCII'.ord($")."\n";
# Ausgabe:
# Start Index =   = ASCII 32
Tipp: Jede Änderung einer vor-definierten globalen Variablen sollte man - wenn überhaupt notwendig - auf einen klar begrenzten Bereich beschränken.
Die Anweisung local begrenzt die Wirkung der folgenden Anweisung auf den mit {} bezeichneten Block.

Beispiel:
Das Array @ar wird zuerst mit dem vor-definierten List-Separator (Leerzeichen) ausgegeben.
Danach wird ein * als neues Trennzeichen festgelegt (schlechter Stil).
Im folgenden Block wird das Trennzeichen lediglich lokal (innerhalb des Blocks) geändert (besserer, sicherer).
Nach dem Block gilt wieder das ursprüngliche bzw. geänderte Trennzeichen.
@ar=(11...14);
print "ar = @ar\n";
# Ausgabe: ar = 11 12 13 14


$" = '*';
print "ar = @ar\n";
# Ausgabe: ar = 11*12*13*14


{
local $" = '-';
print "ar = @ar\n";
# Ausgabe: ar = 11-12-13-14
}

print "ar = @ar\n";
# Ausgabe: ar = 11*12*13*14

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-Syntax

Diese 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 Argumenten

In 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;
}

Perl-Module

Perl bietet eine große Anzahl zusätzlicher Module mit spezialisierten Funktionen.
Am Server ihres Web-Providers können sie keine Module installieren. Für den eigenen Gebrauch können die Module jedoch praktische Funktionen enthalten, die evtl. viel Arbeit sparen. Zum Thema Arrays & Hashes werden besonders viele Module angeboten.
Das Stichwort array liefert >80 Module, hash liefert >150 Module.
Beispiele für weitere Stichworte: parse, sort, ...

Modul Hash

Dieses Modul enthält einige Funktionen zur Erhöhung der Sicherheit bei der Arbeit mit Hashes. Das Modul ist in der Perl-Grundversion nicht enthalten, und muss importiert und vom Programm zur Ausführungszeit geladen werden. Das erfolgt normalerweise am Beginn einer Programm-Datei
use strict;
use Hash::Util;
# Anfangswerte für diese Demo
my(%ha);
%ha = ('r'=>123,'g'=>234,'b'=>0);

Funktion lock_hash

sperrt ein komplettes Hash gegen jede Änderung. Alle vorhandenen Schlüssel und Werte können gelesen (read only), jedoch nicht verändert werden.

Funktion unlock_hash

hebt die Sperre auf.
lock_hash(%ha);
unlock_hash(%ha);

Funktion lock_keys

beschränkt den Bereich zulässiger Schlüssel.
Das ist ein wichtiger Aspekt zur Sicherheit, speziell gegen unabsichtliche Fehlbedienung eines Programms, oder gegen unerwartete Bedingungen bei der Ausführung. Insbesondere bei Verwendung von Hashes durch viele oder unübersichtlich große Programme sollte diese Beschränkung unbedingt verwendet werden.
+ Wenn als Argument nur das Hash angegeben wird, dann sind die Schlüssel auf die bereits vorhandenen Werte beschränkt. Neue Schlüssel können nicht angelegt werden. Wenn Elemente gelöscht werden bleiben deren schlüssel dennoch erlaubt.
+ Wenn als 2. Argument ein Array von Strings angegeben wird, dann sind die Schlüssel auf die in diesem Array vorhandenen Werte beschränkt.

Funktion unlock_keys

hebt die Beschränkung der Schlüssel auf.
lock_keys(%ha);
my @ka=('r','g','b');
lock_keys(%ha, @ka);
unlock_keys(%ha);

Funktion lock_value

sperrt ein einzelnes Hash-Element gegen Änderung seines Wertes.
lock_value(%ha,'r');
unlock_value(%ha,'r');

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 {
my($s)=@_;
my($c,$h)=(0,0);
foreach $c(unpack('c*',$s)) {
$h=(($h*33)+$c) % 0xFFFF;
}
return $h;
}