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

| # Referenzen bzw. Zeiger (Variablen)
| Allgemeines zu Referenzen in Perl Referenzen auf Skalare Referenzen auf Arrays Referenzen auf Hashes Referenzen auf Subroutinen Referenzen auf Dateihandles Referenzen auf Referenzen

## Allgemeines zu Referenzen in Perl

Wenn Sie sich in der Sprache C auskennen, wissen Sie, was Zeiger sind, und wie effizient das Programmieren dadurch werden kann. Referenzen sind Zeiger auf andere Inhalte, z.B. auf zuvor definierte Variablen (egal ob Skalare, Listen oder Hashes). Über Referenzen können Sie den Inhalt eines Skalars, einer Liste oder eines Hashs genauso ansprechen wie über den Originalnamen. Ferner können Sie Referenzen auf Subroutinen setzen. Referenzen sind Skalare, die aber keine "Nutzwerte" speichern, sondern lediglich Arbeitsspeicheradressen von anderen Variablen oder von Subroutinen.

Für Anfänger ist erst einmal nicht so recht ersichtlich, wozu solche Referenzen oder Zeiger gut sein sollen. Denn die Vorteile der Referenzen liegen zum einen auf einem Gebiet, mit dem Perl einen ansonsten verschont - nämlich der effizienten Arbeitsspeicherverwaltung. Es kostet einfach weniger Arbeitsspeicher und weniger Rechenlast, einer Funktion nicht eine Zeichenkette mit vielen tausend Zeichen zu übergeben, sondern nur eine Referenz auf diese Zeichenkette. Zum anderen sind Referenzen sinnvoll, wenn es darum geht, komplexe Datenstrukturen aufzubauen.

Referenzen werden vor allem auch in der objektorientierten Programmierung eingesetzt, die mit Perl seit der Version 5 des Perl-Interpreters ebenfalls möglich ist. So erfolgt der Zugriff auf Methoden (Funktionen, Subroutinen) und Eigenschaften (Variablen) eines Objekts über Referenzen. Auch viele moderne Module benutzen diese Technik, und solche Module zu verwenden bedeutet, mit Referenzen zu arbeiten. Deshalb lohnt es auf jeden Fall, sich mit Referenzen zu beschäftigen.

Referenzen in Perl arbeiten anders als etwa im klassischen C. Die berüchtigten "hängenden Zeiger", also Referenzen, die länger leben als das, was mit ihnen referenziert wird, und die in C zu unkontrollierten Programmzuständen führen können, gibt es in Perl nicht. Dort wird der Wert, auf den die Referenz zeigt, solange im Speicher gehalten, wie die letzte Referenz darauf lebt.
Unter anderem aus diesem Grund ist eine Zeigerarithmetik (also das Rechnen mit Zeigern), wie sie oftmals in C praktiziert wird, in Perl nicht möglich.

## Referenzen auf Skalare

Sie können einen Zeiger auf einen Skalar erzeugen und über diesen Zeiger auf den Skalar und seinen gespeicherten Wert zugreifen.

### 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 $Satz = "HTML - How To Make Love";
    my $Satzzeiger = \$Satz;

    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 "Variablentyp und Speicheradresse von \$Satz: $Satzzeiger<br>\n";
    print "Inhalt von \$Satz: ${$Satzzeiger}\n";

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

### Erläuterung:

Das Beispiel definiert zunächst einen gewöhnlichen Skalar namens `$Satz` und initialisiert ihn mit einem Wert. Anschließend wird eine Referenz auf diesen Skalar deklariert. Die Referenz erhält im Beispiel den Namen `$Satzzeiger`. Es handelt sich dabei von der Syntax her also offensichtlich um einen Skalar. Was diesen Skalar zu einer Referenz macht, ist der Wert, der ihm bei der Initialisierung zugewiesen wird. Der zugewiesene Wert `\$Satz` signalisiert Perl durch den anfänglichen Backslash, dass in `$Satzzeiger` die Referenz auf `$Satz` gespeichert werden soll. Würde der Backslash fehlen, dann würde `$Satzzeiger` einfach nur eine Kopie des Wertes von `$Satz` zugewiesen.

Das Beispiel erzeugt HTML-Code. Dabei gibt es zwei Informationen aus: einmal den Inhalt von `$Satzzeiger` (damit man sieht, was in so einer Referenz gespeichert ist - der ausgegebene Wert enthält so etwas wie `SCALAR(0xb67d20)`), und einmal den Inhalt von `$Satz`, jedoch nicht über `$Satz` selber, sondern mit Hilfe der Referenz `$Satzzeiger`. Der angegebene Beispiel-Code enthält außerdem eine andere kleine Gemeinheit, die zu Verwirrung führen kann: an der Stelle, wo `\$Satz` innerhalb der `print`-Anweisung vorkommt, hat der Backslash eine andere Bedeutung als zuvor beim Initialisieren der Referenz! An dieser Stelle dient der Backslash zum Maskieren des Zeichens `$`. Durch die Maskierung wird erreicht, dass an der Stelle die Zeichenkette `$Satz` ausgegeben wird und nicht etwa der in `$Satz` gespeicherte Wert.

Um mit einer Referenz auf den in diesem Skalar gespeicherten Wert zugreifen zu können, müssen Sie die Syntax benutzen wie im Beispiel mit `${$Satzzeiger}` gezeigt. Die Referenz, in diesem Fall `$Satzzeiger`, wird dabei in geschweiften Klammern und mit einem zusätzlich vorangestellten Dollarzeichen notiert. `${$Satzzeiger}` liefert im Beispiel also `HTML - How To Make Love`.

### Beachten Sie:

Die Syntax zur Dereferenzierung mit der geschweiften Klammer ist die Variante, die immer funktioniert. Perl bietet Ihnen auch hier die Möglichkeit, die Notation abzukürzen. Statt `${$Satzzeiger}` können Sie auch `$$Satzzeiger` notieren, wenn es im Kontext eindeutig ist.

## Referenzen auf Arrays

Sie können einen Zeiger auf einen Array erzeugen und über diesen Zeiger auf den Array und alle seine Elemente zugreifen.

### 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 @Saetze = ( "HTML - How To Make Love. ",
                   "XHTML - Extended How To Make Love. ",
                   "XML - Extended Making Love." );
    my $Saetzezeiger = \@Saetze;

    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 "Variablentyp und Speicheradresse von \@Saetze: $Saetzezeiger<br>\n";
    print "Inhalt von \@Saetze: @{$Saetzezeiger} <br>\n";
    print "Inhalt von \$Saetze[2]: $Saetzezeiger->[2] <br>\n";

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

### Erläuterung:

Im Beispiel wird zunächst ein Array namens `@Saetze` deklariert und mit Anfangswerten initialisiert. Anschließend wird eine Referenz auf diesen Array mit Namen `$Saetzezeiger` deklariert. Die Referenz selber ist ein Skalar, sichtbar an dem vorangestellten Dollarzeichen. Eine Referenz auf den Array wird dieser Skalar durch den zugewiesenen Wert `\@Saetze`. Der Backslash vor dem Klammeraffen signalisiert Perl, dass es eine Referenz ist. Würde der Backslash an dieser Stelle fehlen, dann würde in `$Saetzezeiger` übrigens die Anzahl der Array-Elemente von `@Saetze` gespeichert!

Das Beispiel erzeugt HTML-Code und gibt dabei verschiedene Daten aus. In der ersten `print`-Anweisung wird zum besseren Verständnis der gespeicherte Wert der Referenz `$Saetzezeiger` ausgegeben - das ist so etwas wie `ARRAY(0xb65b28)`.
Die zweite `print`-Anweisung gibt den kompletten Inhalt des Arrays aus. Auf den Array als Ganzes wird dabei über die Referenz mit der Syntax `@{$Saetzezeiger}` zugegriffen. Die Referenz steht also in geschweiften Klammern, und unmittelbar davor ist ein Klammeraffe notiert, der auf die Liste hinweist.
In der dritten `print`-Anweisung wird ein bestimmtes Element von `@Saetze` ausgegeben, nämlich das dritte Listenelement. Direkt notiert wäre dieses Element mit `$Saetze[2]` ansprechbar. Im Beispiel wird es jedoch über die Referenz angesprochen, und dabei lautet die Syntax `$Saetzezeiger->[2]`. Notiert wird also die Referenz, gefolgt von dem Pfeiloperator `->` und dem gewünschten Listenelement in eckigen Klammern. Wichtig ist dabei, dass innerhalb der Zeichenkette `$Saetzezeiger->[2]` keine Leerzeichen vorkommen.

Die Backslashes vor `\@Saetze` und `\$Saetze[2]` innerhalb der `print`-Anweisungen haben wie schon im Beispiel zu Skalaren nichts mit Referenzen zu tun, sondern dienen der Maskierung.

### Beachten Sie:

Wie auch bei Skalarreferenzen bietet Perl Ihnen unterschiedliche Notationsmöglichkeiten. So können Sie statt `@{$Saetzezeiger}` auch `@$Saetzezeiger` notieren und statt `$Saetzezeiger->[2]` können Sie auch die "Urvariante" `${$Saetzezeiger}[2]` oder die Variante `$$Saetzezeiger[2]` verwenden.

## Referenzen auf Hashes

Sie können eine Referenz auf einen Hash erzeugen und über diese Referenz auf den Hash als Ganzes sowie auf dessen einzelne Schlüssel und Werte zugreifen.

### 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 %Sprachen = ( HTML => "How To Make Love. ",
                     XHTML => "Extended How To Make Love. ",
                     XML => "Extended Making Love. " );
    my $Sprachenzeiger = \%Sprachen;

    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 "Variablentyp und Speicheradresse von %Sprachen: $Sprachenzeiger<br>\n";
    print "Inhalt von \%Sprachen: ", %{$Sprachenzeiger}," <br>\n";
    print "Bedeutung von XML: $Sprachenzeiger->{XML} <br>\n";

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

### Erläuterung:

Im Beispiel wird zunächst ein Hash namens `%Sprachen` deklariert und mit Anfangswerten initialisiert. Anschließend wird eine Referenz auf diesen Hash mit Namen `$Sprachenzeiger` deklariert. Die Referenz selber ist ein Skalar, der durch den zugewiesenen Wert `\%Sprachen` zur Referenz wird. Der Backslash vor dem Prozentzeichen signalisiert die Referenz auf den Hash.

Das Beispiel erzeugt HTML-Code und gibt dabei verschiedene Daten aus. In der ersten `print`-Anweisung wird zum besseren Verständnis der gespeicherte Wert der Referenz `$Sprachenzeiger` ausgegeben - das ist so etwas wie `HASH(0xb65b28)`.
Die zweite `print`-Anweisung gibt den kompletten Inhalt des Hashes aus. Auf den Hash als Ganzes wird über die Referenz mit der Syntax `%{$Sprachenzeiger}` zugegriffen. Die Referenz steht also in geschweiften Klammern, und unmittelbar davor ist ein Prozentzeichen notiert, das auf den Hash hinweist.
In der dritten `print`-Anweisung wird direkt das Hash-Element mit dem Schlüssel `XML` angesprochen. Direkt notiert wäre dieses Element mit `$Sprachen{XML}` ansprechbar. Im Beispiel wird es jedoch über die Referenz angesprochen, und dabei lautet die Syntax `$Sprachenzeiger->{XML}`. Notiert wird also die Referenz, gefolgt von dem Pfeiloperator `->` und dem gewünschten Hash-Schlüssel in geschweiften Klammern. Innerhalb von `$Sprachenzeiger->{XML}` dürfen in diesem Kontext (also innerhalb von Zeichenketten) keine Leerzeichen vorkommen.

### Beachten Sie:

Wie bei Array-Referenzen bietet Perl Ihnen auch hier unterschiedliche Notationsmöglichkeiten. So können Sie wieder statt `%{$Sprachenzeiger}` auch `%$Sprachenzeiger` notieren, und statt `$Sprachenzeiger->{XML}` können Sie auch die Varianten `${$Sprachenzeiger}{XML}` oder `$$Sprachenzeiger{XML}` verwenden.

## Referenzen auf Subroutinen

Sie können eine Referenz auf eine Subroutine setzen und über diese Referenz die Subroutine aufrufen.

### 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);

    sub Zufallswert {
     return int(rand(1000) + 1);
    }

    my $Ergebnis = Zufallswert();
    my $Subroutinenzeiger = \&Zufallswert;
    my $Referenzergebnis = &{$Subroutinenzeiger}();

    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 "Ergebnis: $Ergebnis<br>\n";
    print "Subroutinenzeiger: $Subroutinenzeiger<br>\n";
    print "Referenzergebnis: $Referenzergebnis<br>\n";

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

### Erläuterung:

Im Beispiel wird eine Subroutine namens `Zufallswert` notiert. Diese Subroutine ermittelt mit Hilfe der Perl-Funktionen rand und int eine zufällige Ganzzahl zwischen 1 und 1000 und gibt die ermittelte Zahl mit return zurück.

Mit der Anweisung `my $Ergebnis = &Zufallswert();` wird die Subroutine aufgerufen. Der Rückgabewert, also eine ermittelte Zufallszahl, wird im Skalar `Ergebnis` gespeichert.
Mit der Anweisung `my $Subroutinenzeiger = \&Zufallswert;` wird dagegen nur ein Zeiger auf die Subroutine `Zufallswert` deklariert. Die Funktion wird dabei nicht aufgerufen! Dass es sich um eine Referenz handelt, bewirkt die Syntax `\&Zufallswert` beim zugewiesenen Wert. Der Backslash am Anfang signalisiert die Referenz und das Ampersand-Zeichen `&` eine Subroutine. Dahinter folgt der Name der Subroutine.
Mit der Anweisung `my $Referenzergebnis = &{$Subroutinenzeiger}();` wird die Subroutine `Zufallswert` wieder aufgerufen. Diesmal aber nicht wie in der ersten Anweisung direkt, sondern über die zuvor definierte Referenz. Die Syntax ist dabei so, dass die Referenz in geschweiften Klammern steht und ein Ampersand-Zeichen `&` vorangestellt bekommt.
Die leeren runden Klammern hinter dem Namen der Subroutine sind übrigens nicht zwingend nötig. Der Rückgabewert des zweiten Aufrufs von `Zufallswert` wird in dem Skalar `$Referenzergebnis` gespeichert.

Das Beispiel sendet HTML-Code an den Browser und gibt dabei die drei Werte von `$Ergebnis`, `$Subroutinenzeiger` und `$Referenzergebnis` aus. Während die beiden Skalare `$Ergebnis` und `$Referenzergebnis` eine Zufallszahl zwischen 1 und 1000 enthalten, ist der Inhalt von `$Subroutinenzeiger` nur der Zeigertyp und die Arbeitsspeicheradresse, z.B. so etwas wie `CODE(0xb65b28)`.

### Beachten Sie:

Perl bietet Ihnen auch bei der Dereferenzierung von Code-Referenzen unterschiedliche Notationsmöglichkeiten. So können Sie analog zu Skalar- und Array-Referenzen statt `&{$Subroutinenzeiger}()` auch `&$Subroutinenzeiger()` oder `$Subroutinenzeiger->()` notieren.

## Referenzen auf Dateihandles

Bei Funktionen für Ein-/Ausgabe und Lesen/Schreiben von Daten haben Sie viel mit Dateihandles zu tun. Dateihandles verhalten sich anders als gewöhnliche Variablen. So können Sie ihnen keine direkten Werte zuweisen, sondern nur die Werte nutzen, die dem Dateihandle bei Bedarf vom Perl-Interpreter selbst zugewiesen werden. Die Werte beinhalten perl-interne Informationen über den Ein-/Ausgabekanal, auf den Sie mittels des Dateihandles zugreifen. Für Sie als Benutzer ist allerdings nur der Name des Handles interessant, um den Rest kümmert sich der Perl-Interpreter selbst.
Auf ein solches Dateihandle können Sie ebenfalls eine Referenz setzen. Hier liegt eine weitere Besonderheit gegenüber gewöhnlichen Variablen in Perl: Sie müssen diese Referenz zur Benutzung des Dateihandles nicht explizit dereferenzieren. Das erledigt der Perl-Interpreter automatisch, wenn es notwendig ist.

### 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);

    open(DATEI, "</tmp/server.cfg") || die "nicht gefunden";
    my $HandleReferenz = \*DATEI;
    my @Zeilen = <$HandleReferenz>;
    my $Zeilenzahl = @Zeilen;
    my $HandleName = *{$HandleReferenz};
    close($HandleReferenz);

    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 "eingelesene Zeilen: $Zeilenzahl<br>\n";
    print "$HandleReferenz<br>\n";
    print "$HandleName<br>\n";

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

### Erläuterung:

Das Beispiel öffnet mit der open-Funktion von Perl eine Datei. Dabei ist `DATEI` der Name für das Dateihandle, über das auf die Datei zugegriffen wird. Dieser Name ist im Rahmen der Regeln zur Namensvergabe frei wählbar, jedoch sollten Sie per Konvention keine Kleinbuchstaben verwenden. Wenn Sie die w-Option des Perl-Interpreters verwenden, erhalten Sie bei unpassend gewählten Namen eine Warnung. Normalerweise könnte anschließend mit einer Anweisung wie `my @Zeilen = <DATEI>;` der Inhalt der Datei eingelesen werden. Im obigen Beispiel geschieht das Einlesen jedoch indirekt über eine Referenz.
Mit der Anweisung `my $HandleReferenz = \*DATEI;` wird ein Zeiger auf den Namen (bzw. den Eintrag in der perl-internen Symboltabelle) `DATEI` deklariert. Der Backslash am Anfang der Zuweisung signalisiert die Referenz und das Sternzeichen `*` einen Symboltabelleneintrag (einen so genannten Typeglob). Dahinter folgt der Name des Dateihandles.
Mit `my @Zeilen = <$HandleReferenz>;` kann der Inhalt der Datei nun über die Referenz auf das Dateihandle eingelesen werden. Statt `<DATEI>` wird also einfach `<$HandleReferenz>` notiert. Die Referenz dazu wird vom Perl-Interpreter selbst aufgelöst.
Die Anweisung `my $Zeilenzahl = @Zeilen;` ermittelt die Anzahl der eingelesenen Zeilen zur späteren Kontrollausgabe.
In der Anweisung `my $HandleName = *{$HandleReferenz};` wird die Referenz auf das Dateihandle nochmals explizit dereferenziert. In dieser Notation, also in geschweiften Klammern und mit voranstehendem Sternzeichen, wird der in `$HandleReferenz` gespeicherte Name des Handles ermittelt, im Beispiel also `DATEI`. Dabei wird allerdings auch der aktuelle Namensraum (package) mit ermittelt (siehe dazu auch die Perl-Funktion package). Der tatsächlich ermittelte Wert im obigen Beispiel ist `*main::DATEI`. Dabei ist `main` einfach der voreingestellte Namensraum von Perl, wenn - wie hier im Beispiel auch - kein anderer Namensraum angegeben wurde. `main::DATEI` wird als voll qualifizierter Name bezeichnet, da er genau aussagt, in welchem Namensraum `DATEI` zu finden ist.

Das Beispiel erzeugt HTML-Code und gibt dabei die ermittelten Werte aus. Der Wert von `$HandleReferenz` ist so etwas wie `GLOB(0xb67968)`. Dabei steht `GLOB` für den Referenztyp "Typeglob".

## Referenzen auf Referenzen

Es mag sich zunächst nach einer theoretischen Spielerei anhören, mit Referenzen auf Referenzen zu arbeiten. Bei komplexen Datenstrukturen kann es jedoch durchaus sinnvoll sein, solche Referenzen einzusetzen. Gerade beim Zugriff auf Einzelwerte aus einer solchen komplexen Datenstruktur erreicht Perl eine geradezu klassische Schönheit in der Notation.

### 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 $Haus = "Einfamilienhaus in Fertigbauweise";
    my @Autos = ("VW","Opel","Audi","Porsche");
    my %Familie = (Frau => "Eva", Tochter => "Anja", Sohn => "Florian");
    my %Zeigerhash = (Hauszeiger => \$Haus, Autozeiger => \@Autos, Familienzeiger => \%Familie);
    my $Zeiger = \%Zeigerhash;

    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 "(1.) $Zeiger->{Hauszeiger}<br>\n";
    print "(2.) ${$Zeiger->{Hauszeiger}}<br>\n";
    print "(3.) $Zeiger->{Autozeiger}<br>\n";
    print "(4.) @{$Zeiger->{Autozeiger}}<br>\n";
    print "(5.) $Zeiger->{Autozeiger}->[2]<br>\n";
    print "(6.) $Zeiger->{Autozeiger}[3]<br>\n";
    print "(7.) $Zeiger->{Familienzeiger}<br>\n";
    print "(8.)", %{$Zeiger->{Familienzeiger}},"<br>\n";
    print "(9.) $Zeiger->{Familienzeiger}->{Frau}<br>\n";
    print "(10.) $Zeiger->{Familienzeiger}{Sohn}<br>\n";

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

### Erläuterung:

Das Beispiel deklariert zunächst einen Skalar `$Haus`, einen Array `@Autos` und einen Hash `%Familie`. Daraufhin werden Zeiger bzw. Referenzen auf diese Variablen definiert. Da es sich jedoch um eine Serie von Zeigern handelt, werden sie nicht einzeln als Skalare deklariert, sondern in einem Hash namens `%Zeigerhash`. Jedes Element eines Hashs oder einer Liste kann ja einen Skalar speichern, und da Referenzen Skalare sind, ist es also kein Problem, Hashes oder Listen von Referenzen zu erzeugen. Der Hash im Beispiel erhält als Zuweisung beispielsweise einen Schlüssel namens `Hauszeiger`, mit dem eine Referenz auf den Skalar `Haus` verknüpft ist, sichtbar am beginnenden Backslash `\$Haus`. Ebenso wird es mit den anderen Referenzen innerhalb des Hashes gemacht.

Nun könnte man ja über die Hashvariable `%Zeigerhash` auf die Referenzen und ihre Werte zugreifen. Im Beispiel wird jedoch noch ein Skalar namens `$Zeiger` deklariert, der eine Referenz auf den Hash `%Zeigerhash` ist, sichtbar an der Notation `\%Zeigerhash` bei der Zuweisung. `$Zeiger` ist damit also eine Referenz auf einen Hash aus Referenzen.

Das Beispiel-Script hat damit allerlei Daten beisammen und kann bei der Zusammenstellung von HTML-Code die verschiedensten Werte ausgeben. Der Einfachheit halber erscheinen die Ausgaben nummeriert:

(1.) gibt so etwas aus wie: `SCALAR(0xb65b7c)`, denn `$Zeiger->{Hauszeiger}` bedeutet den Wert des Hash-Elements mit dem Schlüssel `Hauszeiger`, und das ist die Referenz `\$Haus`.
(2.) gibt aus: `Einfamilienhaus in Fertigbauweise`, denn `${$Zeiger->{Hauszeiger}}` bedeutet den Wert des Wertes vom Hash-Element mit dem Schlüssel `Hauszeiger`, also letztlich den Wert der Referenz `\$Haus`. Um den Wert des Wertes zu ermitteln, wird um den Ausdruck aus (1.) einfach noch einmal eine geschweifte Klammer gesetzt und ein Dollarzeichen vorangestellt.
(3.) gibt so etwas aus wie: `ARRAY(0xb65b4c)`, denn `$Zeiger->{Autozeiger}` bedeutet den Wert des Hash-Elements mit dem Schlüssel `Autozeiger`, und das ist die Referenz `\@Auto`.
(4.) gibt aus: `VW Opel Audi Porsche`, denn `@{$Zeiger->{Autozeiger}}` bedeutet den Wert des Wertes vom Hash-Element mit dem Schlüssel `Autozeiger`, also letztlich den Wert der Referenz `\@Autos`, und das ist die gesamte Liste `@Autos`. Um den Wert des Wertes zu ermitteln, wird um den Ausdruck aus (3.) einfach noch einmal eine geschweifte Klammer gesetzt und ein Klammeraffe vorangestellt.
(5.) gibt aus: `Audi`, denn `$Zeiger->{Autozeiger}->[2]` bedeutet den Wert des dritten Elements des Wertes vom Hash-Element mit dem Schlüssel `Autozeiger`, also letztlich den dritten Wert der Referenz `\@Autos`, und das ist das dritte Element von `@Autos`.
(6.) gibt aus: `Porsche`. Dies ist eine verkürzte Schreibweise für das gleiche, was bei (5.) passiert. Es genügt, den ersten Pfeiloperator `->` zu notieren.
(7.) gibt so etwas aus wie: `HASH(0xb65b58)`, denn `$Zeiger->{Familienzeiger}` bedeutet den Wert des Hash-Elements mit dem Schlüssel `Familienzeiger`, und das ist die Referenz `\%Familie`.
(8.) gibt aus: `SohnFlorianTochterAnjaFrauEva`, denn `%{$Zeiger->{Familienzeiger}}` bedeutet den Wert des Wertes vom Hash-Element mit dem Schlüssel `Familienzeiger`, also letztlich den Wert der Referenz `\%Familie`, und das ist der gesamte Hash `%Familie`. Um den Wert des Wertes zu ermitteln, wird um den Ausdruck aus (7.) einfach noch einmal eine geschweifte Klammer gesetzt und ein Prozentzeichen vorangestellt.
(9.) gibt aus: `Eva`, denn `$Zeiger->{Familienzeiger}->{Frau}` bedeutet den Wert des Hash-Elements mit dem Schlüsselnamen `Frau` des Wertes vom Hash-Element mit dem Schlüssel `Familienzeiger`.
(10.) gibt aus: `Florian`. Dies ist eine verkürzte Schreibweise für das gleiche, was bei (9.) passiert und hat den gleichen Grund wie bei (6.).

| Vordefinierte Variablen in Perl
| Hashes (Variablen)

© 2007 Impressum