Perl 6

Die Zukunft des Programmierens

Hashes oder Assoziative Arrays

Listen sind einfach eine Sammlung von Elementen, auf die man mit ganzen Zahlen als Index zugreifen kann.

Ein Assoziatives Array, auf Englisch auch Hash Table oder kurz Hash genannt, speichert ebenfalls Elemente, verwendet aber Strings anstatt ganzer Zahlen als Index.

Ein Hash beginnt in Perl mit einem Prozentzeichen %:

use v6;

my %autoren = ( 
    "Linux"   => "Linus Torvalds",
    "Perl"    => "Larry Wall",
    "Pugs"    => "Audrey Tang",
    "Dos"     => "Bill Gates",
    );

my $programm = "Perl";

say %autoren{$programm}, " hat $programm geschrieben";
# Ausgabe: Larry Wall hat Perl geschrieben

Dieses kleine Programm speichert Kombinationen von Programmen und ihren Autoren in einem Hash %autoren ab. Dazu wird dem Hash eine Liste von Paaren zugewiesen, wobei ein Paar in der Form schlüssel => wert geschrieben wird.

Dann wird auf ein Element des Hashes zugegriffen, indem der Schlüssel dahinter in geschweiften Klammern angegeben wird: %autoren{$programm}.

Wie auch bei Arrays kann man einem Hash auch im Nachhinein noch einen Wert einfügen:

%autoren{"perl-6.de"} = "Moritz Lenz";

Wenn man einem Hash ein Element hinzufügen will, dessen Schlüssel schon einmal vorhanden ist, wird der alte Werte überschrieben:

%autoren{"Perl"} = "Die Perl-Community";

say %autoren{$programm}, " hat $programm geschrieben";
# Ausgabe: Die Perl-Community hat Perl geschrieben

Einfachere Syntax

Da man relativ häufig einen konstanten String benutzt um auf ein Element eines Hashes zuzugreifen, gibt es dafür eine eigene Syntax:

%autoren<Perl>;     # das gleiche wie %autoren{"Perl"}

# Wenn man keine Leerzeichen im Schlüssel verwendet, kann man die
# Anführungszeichen um die Schlüssel weglassen:
my %autoren = ( 
    Linux     => "Linus Torvalds",
    Perl      => "Larry Wall",
    Pugs      => "Audrey Tang",
    Dos       => "Bill Gates",
    );

Hashes ausgeben

Wie auch Listen kann man Hashes mit for-Schleifen ausgeben. Dazu benutzt man die Funktion kv, die bei jedem Aufruf ein neues Paar von Schlüssel und Wert zurückliefert:

for %autoren.kv -> my $projekt, $autor {
    say "$projekt ist von $autor gestartet worden";
}

Wenn Sie das Programm ausführen, werden Sie vielleicht bemerken, dass die Reihenfolge der Ausgabe nicht mit der übereinstimmt, in der sie ursprünglich geschrieben wurde. Tatsächlich geht die Information über die Reihenfolge der Elemente beim einfügen in den Hash verloren. Wenn man das Programm mehrfach startet, kann sogar bei jedem Durchlauf eine andere Reihenfolge bei der Ausgabe herauskommen.

Wenn man eine feste Reihenfolge möchte, kann man die Schlüssel eines Hashs vor dem ausgeben sortieren:

for %autoren.keys.sort -> my $projekt {
    my $autor = %autoren{$projekt};
    say "$projekt ist von $autor gestartet worden";
}

Komplexe Datenstrukturen

Man kann problemlos Listen und Hashes in Listen und Hashes speichern. Damit kann man sich beliebig komplizierte Datenstrukturen bauen. Hier erst mal ein einfaches Beispiel für Listen in Hashes:

my %autoren  = (
    Linux      => ["Linus Torvalds", "Andrew Morton", "Chris Wright"],
    Pugs       => ["Audrey Tang", "Damian Conway"],
    Perl       => ["Larry Wall", "Randal Schwartz"], 
    );
# Die Listen sind alles andere als vollständig

# Alle Projekte mit Autoren ausgeben:
for %autoren.kv -> my $projekt, @autoren {
    say "Autoren von $projekt: ", @autoren.join(", ");
}

# Einen Autor zum Perl-Projekt hinzufügen:
%autoren{"Perl"}.push("Tom Christiansen");
# (push fügt einem Array ein Element hinzu)

Die Verschachtelungen können beliebig sein, also z.B. Hashes in Hashes in Listen, oder wie auch immer man es braucht:

my %autoren  = (
    "Linux"    => [
        {
            Person          => 'Linus Torvalds',
            Position        => 'Gründer',
            Arbeitgeber     => 'Linux Foundation',
        },
        {
            Person          => 'Andrew Morton',
            Position        => 'Maintainer des 2.6er Kernels',
            Arbeitgeber     => 'Google',
        }
    ],
    "Perl"    => [
        {
            Person          => "Larry Wall", 
            Position        => 'Wohlmeinender Diktator',
        },
    ],
    );