SELFHTML: Perl / Perl-Sprachelemente / Hashes (Variablen)
Author: Redaktion SELFHTML, selfhtml81@selfhtml.org
Description: Was Hashes in Perl sind, wie sie deklariert werden und wie sie sich verwenden lassen.
Keywords: SELFHTML, Perl, Hashes
Date: 2005-11-09T00:29:27+01:00

| # Hashes (Variablen)
| Hashes deklarieren und Werte zuweisen Auf einzelne Schlüssel und Werte zugreifen Funktionen und Operationen zum Manipulieren von Hashes

## Hashes deklarieren und Werte zuweisen

Gewöhnliche Listen bzw. Arrays bestehen aus einer Reihe von Werten, die über Indexnummern, beginnend bei 0, ansprechbar sind. So ist das 8. Element eines Arrays mit dem Namen `@Listenname` über `$Listenname[7]` ansprechbar. Ein assoziativer Array, in Perl als Hash bezeichnet, speichert dagegen pro Element zwei Werte: einen Namen und einen Wert. Werte innerhalb eines Hashs werden dann nicht über Indexnummern angesprochen, sondern über den zugehörigen Namen "assoziiert". Der Name wird daher auch als "Schlüssel" bezeichnet. Über den Schlüssel ist der Zugriff auf die damit verknüpften Daten möglich.

### Beispiel eines vollständigen CGI-Scripts:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my %Daten = ("Name","Jana","Alter",23,"Ort","Berlin");
    my %bessereDaten = (Name => "Jana", Alter => 23, Ort => "Berlin");

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Testausgabe</title>\n";
    print "</head><body>\n";

    print "<pre>",%Daten,"</pre>\n";
    print "<pre>",%bessereDaten,"</pre>\n";

    print "</body></html>\n";

### Erläuterung:

Im Beispiel werden zwei Hashes namens `%Daten` und `%bessereDaten` deklariert. "Deklaration" bedeutet bei Hashes das gleiche wie bei Arrays. Ein Hash wird durch das Prozentzeichen `%` eingeleitet. Dahinter folgt der Name des Hashes. Bei der Deklaration eines Hashes können Sie Anfangswerte zuweisen oder auch nicht. In beiden obigen Beispielen werden Anfangswerte zugewiesen. Dabei gibt es zwei unterschiedliche Notationsweisen, von denen diejenige, die bei `%bessereDaten` angewendet wird, die übersichtlichere und daher empfehlenswertere ist. Sie können die Werte wie im ersten Hash gezeigt notieren. Dabei wird wie in einer Liste alles durch Kommata getrennt. Das erste, dritte, fünfte usw. Element bezeichnet jedoch einen Namen, und das zweite, vierte, sechste usw. Element den zugehörigen Wert. In der empfehlenswerteren Notation kommt dies besser zum Ausdruck. Dabei werden die Namen-Wert-Paare durch den Zeigeoperator `=>` (der hier ein Synonym für das Komma darstellt, weshalb er auch als fat comma bezeichnet wird) getrennt, und Kommata werden nur zwischen den Paaren notiert. Bei der Notationsweise mit dem Operator `=>` dürfen die Anführungszeichen bei den Namen, also den Schlüsseln, entfallen, wenn sie den Regeln der Namensvergabe genügen. Bei der anderen Notation mit Komma-Trennung zwischen Schlüssel und Wert sind die Anführungszeichen dagegen auch bei den Schlüsseln Pflicht. Die beiden Beispiel-Hashes zeigen diesen Unterschied.

Wie bei Skalaren und Listen können Sie leere Hashes deklarieren. Eine Anweisung wie `my %Daten;` deklariert einen Hash, der jedoch zunächst leer ist.

Wie Listen können auch Hashes bei den eigentlichen Werten nur Skalare enthalten, also Zeichenketten und Referenzen, die Sie auch hier beliebig mischen können. Im obigen Beispiel sind die Einzelwerte `Jana` und `Berlin` Zeichenketten, während `23` eine Zahl ist.

Das Beispiel gibt einfach die beiden Hash-Inhalte aus.

### Beachten Sie:

Skalare, Listen und Hashes haben unterschiedliche Namensräume. Variablen wie `$name`, `@name` und `%name` können also problemlos im gleichen Script vorkommen.

Komplette Hashes, also mit dem Prozentzeichen beginnend, werden innerhalb von Anführungszeichen in `print`-Anweisungen nicht interpretiert. Um einen Hash komplett auszugeben, so wie im obigen Beispiel, müssen Sie die Technik nutzen, mehrere Einzelwerte mit `print` auszugeben, die durch Kommata getrennt sind, wie im obigen Beispiel gezeigt.

Anstelle von konstanten Daten können Sie auch andere Variablen in einen Hash einfügen. Zum Beispiel:
`my $Alter = 23;`
`my %Daten = (Name => "Jana", Alter => $Alter);`

Hashes lassen sich im Zusammenhang mit CGI-Scripts sehr sinnvoll einsetzen. So ist es beispielsweise möglich, den Datenstrom eines vom Anwender ausgefüllten HTML-Formulars in einen Hash einzulesen, wobei als Hash-Schlüssel jeweils der Feldname des Formularelements gespeichert wird und als Wert der Wert, den der Anwender in dem betreffenden Formularelement eingegeben oder ausgewählt hat.

## Auf einzelne Schlüssel und Werte zugreifen

Genau wie bei Listen greifen Sie auf einen Skalar zu, wenn Sie einzelne gespeicherte Werte eines Hashes auslesen oder ihnen Werte zuweisen. Zum Zugriff verwenden Sie den Schlüssel.

### Beispiel eines vollständigen CGI-Scripts:

Anzeigebeispiel: So sieht's aus (Zum Aufruf des Scripts ist eine Internet-Verbindung erforderlich)

    #!/usr/bin/perl -w

    use strict;
    use CGI::Carp qw(fatalsToBrowser);

    my %Daten = (Name => "Jana", Alter => 23, Ort => "Berlin", Bildung => "Abitur");

    print "Content-type: text/html\n\n";
    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
    print "<html><head><title>Testausgabe</title>\n";
    print "</head><body>\n";

    print "$Daten{'Name'} ist $Daten{'Alter'} Jahre alt, wohnt in $Daten{'Ort'} und hat $Daten{'Bildung'}\n";

    print "</body></html>\n";

### Erläuterung:

Im Script wird wieder der Hash `%Daten` deklariert und mit vier Werten initialisiert (diesmal gleich in der besseren Notationsweise). Das Script erzeugt wieder HTML-Code und gibt darin die Daten aus. Diesmal wird dabei jedoch auf die einzelnen Werte des Hashes `%Daten` zugegriffen. Mit `$Daten{'Name'}` wird auf jenes Element des Hashes zugegriffen, das den Schlüssel `Name` hat. Das wie vielte Element im Hash dies ist, brauchen Sie nicht zu wissen. Es genügt, den Schlüssel anzugeben. Damit wird auf den entsprechenden Wert zugegriffen. `$Daten{'Name'}` greift im Beispiel also auf den Wert `Jana` zu. Wichtig ist, dass der Schlüssel in geschweiften Klammern stehen muss. Die Klammern gehören in diesem Kontext (innerhalb von Zeichenketten) zum Variablennamen und müssen direkt hinter dem Namen des Hashes notiert werden (kein Leerraum erlaubt).

Die Syntax wie in `$Daten{'Name'}` zeigt mit dem voranstehenden Dollarzeichen, dass es sich bei einem Hash-Wert um einen Skalar handelt.

### Beachten Sie:

Anstelle von `$Daten{'Name'}` können Sie auch `$Daten{Name}` notieren, also ohne Anführungszeichen. Solange in den geschweiften Klammern nichts weiter steht als ein einzelner Schlüssel, der den Regeln der Namensvergabe genügt, dürfen die Anführungszeichen entfallen.

## Funktionen und Operationen zum Manipulieren von Hashes

Viele Perl-Funktionen gelten für Listen und Hashes, einige davon aber auch nur für Hashes, da das Manipulieren von Hashes einige Besonderheiten aufweist. Ein paar wichtige Möglichkeiten sollen hier mit Verweisen auf die Beschreibung der jeweiligen Funktionen genannt werden.

Mit unbekannten Schlüsseln arbeiten:
Wenn Sie einen Hash mit Werten initialisieren, kennen Sie natürlich auch die Schlüsselnamen. Aber wenn Sie Daten einlesen - etwa HTML-Formulardaten in einem CGI-Script - dann wissen Sie oft nicht, was in einem Hash, der die Daten aufgenommen hat, alles drinsteht. Um sich erst einmal einen Überblick zu verschaffen, welche Schlüssel eines Hashs eingelesen wurden, können Sie die Funktion keys verwenden. Anschließend haben Sie eine Liste mit allen Namen bzw. Schlüsseln des Hashes. Angenommen, Sie haben einen Hash `%Daten` mit Schlüsseln und Werten, die Ihnen zunächst nicht bekannt sind. Dann können Sie mit einer Anweisung wie `@Schluessel = keys(%Daten);` die Schlüssel ermitteln. Anschließend können Sie beispielsweise über `$Daten{$Schluessel[0]}` auf den Wert des Hashes zugreifen, der mit dem Namen assoziiert wird, der nun in `$Schluessel[0]` zu finden ist, ohne den Schlüssel explizit zu kennen.

Werte ändern oder hinzufügen:
Durch eine Anweisung wie `$Daten{Vorname} = "Oliver";` weisen Sie innerhalb des Hashes `%Daten` dem Element mit dem Schlüssel `Vorname` einen Wert zu. Falls bereits ein Schlüssel `Vorname` in dem Hash existiert, wird dessen bisher gespeicherter Wert durch den neu zugewiesenen Wert ersetzt. Wenn der Schlüssel dagegen noch nicht existiert, wird das Schlüssel-Wert-Paar einfach neu in den Hash aufgenommen. Ändern geht also, indem man einem vorhandenen Schlüssel einen Wert zuweist, und Hinzufügen, indem man einem noch nicht vorhandenen Schlüssel einen Wert zuweist.

Schlüssel-Wert-Paar löschen:
Zum Löschen eines kompletten Schlüssel-Wert-Paares bietet Perl die Funktion delete an.

Kompletten Hash löschen:
Zum Löschen aller bisher verwendeten Schlüssel-Wert-Paare initialisieren Sie einfach den Hash neu mit leerem Inhalt: `%Daten = ()`.

Hash-Werte der Reihe nach abarbeiten und sortieren:
Hashes werden intern in einer Datenstruktur gespeichert, die für Effizienz bei Schreib- und Lesezugriffen sorgt. Aufgrund dieser Tatsache ist die Reihenfolge der Schlüssel, wie sie beispielsweise von der Funktion keys geliefert wird, (scheinbar) mehr oder weniger zufällig und stimmt nur in den seltensten Fällen mit der Reihenfolge überein, in der Sie den Hash deklariert haben. Sie haben keine Möglichkeit, diese Reihenfolge zu verändern. Es hält Sie allerdings niemand davon ab, die Hash-Elemente in einer bestimmten Reihenfolge beispielsweise mit einer Schleife zu durchlaufen. So können Sie z.B. mit `@sortierteSchluessel = sort keys %Daten` die Schlüssel des Hashes `%Daten` alphabetisch sortieren und diese sortierte Liste von Schlüsseln dem Array `@sortierteSchluessel` zuweisen. So eine sortierte Liste von Schlüsseln können Sie anschließend (beispielsweise mit einer Schleife) benutzen, um die einzelnen Hash-Elemente in eben dieser sortierten Reihenfolge zu verarbeiten. Dabei können Sie wahlweise nach Schlüsseln oder nach Werten sortieren. Dazu müssen Sie allerdings ein paar Perl-Funktionen sowie eine Schleife anwenden. Im Abschnitt über Schleifen finden Sie eine Beschreibung zum Thema Hashes und Schleifen.

Anzahl Schlüssel-Wert-Paare eines Hashs ermitteln:
Dies können Sie ebenfalls über die Funktion keys lösen. Mit einer Anweisung wie `$Anzahl = keys(%Daten);` speichern Sie im Skalar `$Anzahl` die Anzahl der in `%Daten` vorhandenen Schlüssel und damit der Schlüssel-Wert-Paare. Denn die Funktion `keys` gibt, wenn sie im skalaren Kontext aufgerufen wird, die Anzahl der Schlüssel zurück.

| Referenzen bzw. Zeiger (Variablen)
| Listen bzw. Arrays (Variablen)

© 2007 Impressum