Referenzen (Pointer)


Einführung

Sie kennen Pointer bestimmt aus anderen Programmiersprachen. Pointer sind Speicheradressen von bestimmten Hauptspeicherobjekte. Die Bezeichnung lautet: Ein Pointer zeigt auf etwas. Pointer können dereferenziert werden. Das bedeutet, daß nicht auf den Pointer selbst, sondern auf das vorauf er zeigt, zugegriffen wird.

Einige Programmiersprachen erlauben Pointer-Arithmetik (z.B. C).

Perl unterstützt ab Version 5 auch Pointer. Allerdings handelt es sich bei diesen Pointern und sogenannte smart pointer. Sie werden in Perl Referenzen genannt.

Es gibt zwei Sorten von Referenzen in Perl:

Mehr Details zu Referenzen finden Sie in man perlref.

Symbolische Referenzen

Eine detailliertere Behandlung von Symbolischen Referenzen finden Sie in man perlref.

Einführung und Schreibweise

Symbolische Referenzen sind sehr einfach: Stellen Sie sich vor, daß Sie den Namen einer Variablen in einer anderen Variable speichern. Durch diesen Namen können Sie dann auf die Zielvariable zugreifen:
$var  = "xyzzy";     # irgendeine variable
$nvar = 'var';       # symbolische referenz
print "$nvar\n";     # var
print "$$nvar\n";    # xyzzy
$$nvar = "wizard";   # $var == "wizard"
print "$var\n";      # wizard
Es können auch symbolische Referenzen auf Arrays, Hashes und sogar Subroutines verwendet werden:
# Die Zielvariablen
%cols = ( ... );
@alias = ( ... );
sub add { ... };

# Die Symrefs.
$symhash  = 'cols';
$symarray = 'alist';
$symsub   = 'add';

# Dereferenzierungen:
${$symhash}{'red'} = 0xff0000;
%ncols = %$symhash;

$$symarray[0] = 'new element';
@narray = @$symarray;

&$symsub();
$erg = &{$symsub}(3, 12, 17);

Problem bei Symrefs

Symbolische Referenzen haben ein Problem:
$symvar = "haha";
sub func {
    my $locvar;

    $symvar = 'locvar';
    $$symvar = 1711;     # $locvar == 1711
}

&func();
print "$symvar\n";     # locvar
print "$$symvar\n";    # $locvar NICHT GLOBAL DEFINIERT!!!
Wie leicht zu sehen ist, zeigt nun die symbolische Referenz ins leere. Das wäre bei harten Referenzen nicht passiert!

Harte Referenzen

Harte Referenzen sind echte Referenzen auf Speicherobjekte. Anders als bei Symbolischen Referenzen, geht bei Verlust des Scope der referenzierten Variable ihren Inhalt nicht verloren, solange noch eine harte Referenz darauf zeigt. Erst wenn überhaupt keine Referenzen mehr auf einen Speicherobjekt zeigen, wird dieses Objekt zerstört.

Schreibweise

Harte Referenzen werden durch einen Backslash \ eingeleitet:
$pvar  = \$var;       # Skalar
$parr  = \@arr;       # Array
$phash = \%hash;      # Hash
$psub  = \&subname;   # Subroutine
$pfh   = \*FHANDLE;   # Filehandle
Diese Referenzen werden wie folgt dereferenziert:
$$pvar = "new value";       # skalar

$$parr[3] = "new element";  # array element
@nlist = $$parr;            # ganzes array

%nhash = $$phash;            # ganzes hash
${$phash}{"red"} = 0xff0000; # hash element

&{$psub}(1,2,3);            # subroutine

print $pfh "This goes to FHANDLE\n";

Anonyme Referenzen

Motivation

Bisher haben wir stets Referenzen auf bereits benannte Variablen (Skalare, Hashes, Arrays, Subroutines etc..) betrachtet. Es ist jedoch, wie in anderen Programmiersprachen üblich, möglich, Referenzen auf Heap-Speicher zu definieren. Diese Referenzen zeigen also auf Speicherobjekte, die keinen Namen haben. Darum heißen sie Anonyme Referenzen.

Anonyme Referenzen kennen Sie aus anderen Programmiersprachen: So würde der C-Programmierer die Funktion malloc() verwenden, um neuen Speicherplatz zu allokieren; PASCAL-Kenner würden new verwenden, ebenso C++ und Java Anwender. In allen diesen Fällen wird Hauptspeicher vom Heap allokiert.

Anonyme Listen

Eine anonyme Liste bekommen Sie durch den Eckigen-Klammern Operator: []:
$arrayref        = [ 1, 3, 4711, "hello world" ];
$nestedarrayref1 = [ 5, 2, $arrayref, "bye" ];
$nestedarrayref2 = [ 11, 22, [ 31, 32, 33 ], 44, 55 ];
$e3_matrix       = [ [1,0,0], [0,1,0], [0,0,1] ];
Dereferenziert werden solche Strukturen wie folgt:
print $arrayref->[2];       # 4711
$e3_matrix->[0]->[1] = 7;   # [[1,7,0],...]
$e3_matrix[0][1]     = 3;   # [[1,3,0],...]
Anonyme Listen sind sehr flexibel:
push ($e3_matrix->[0], 2);   # [[1,3,0,2],...]
pop($e3_matrix->[1]);        # [[1,3,0,2],[1,0],[0,0,1]]
$empty = [];                 # leere liste
push ($empty, "hello", "world"); # ["hello", "world"]

Anonyme Hashes

Anonyme Hashes werden durch geschweifte Klammern erzeugt:
$hashref = { "kirk" => "jim t.", "picard" => "jean-luc" };
$empth   = {};
$empth->{"mon"} = "monday";
$empth->{"tue"} = "tuesday";

print ${$hashref}->{"kirk"};        # jim t.
${$hashref}->{"janeway"} = "katherine";
delete $empth->{"mon"};  # no more blue mondays :-)

Anonyme Subroutines

Anonyme Subroutines werden durch das Wörtchen sub ohne Subroutinennamen erzeugt:
$subref = sub { print "hi"; $b=1; };
&$subref();

Komplexe Datenstrukturen

Es ist mit Hilfe von (anonymen) Referenzen möglich, komplexe Datenstrukturen zu erzeugen. Eine Einführung in komplexe Datenstrukturen finden Sie im Kochbuch man perldsc. Wie Sie Listen von Liste, Listen von Hashes etc.. konstruieren können, finden Sie in man perllol. Weitere Beispiele für anonyme Strukturen finden Sie auch in man perldata.

Vorherige Seite, Nächste Seite, Index, Hauptindex.


Copyright © 1997/08/16 by Farid Hajji.