Wie verwende ich Konstanten in Perl?
Das Pragma constant
Zur Definition einer Konstante wird diesem Pragma ein Key/Value Paar mitgegeben.
use constant FILE => "/path/to/file/filename";
Nach dieser Anweisung ist die Verwendung der Bezeichnung FILE synonym zu dem als
Value angegebenen Skalar.
open (FH, FILE) or die FILE . " open failed: [$!]\n";
# do something
close (FH);
Wenn dem Pragma eine Hashreferenz mitgegeben wird, dann wird für jeden key eine Konstante erzeugt
(Perl Versionen >= 5.8):
use constant {
DEUTSCH => "/path/to/file/deutsch.txt",
ENGLISCH => "/path/to/file/englisch.txt",
JAPANISCH => "/path/to/file/japanisch.txt",
SPANISCH => "/path/to/file/spanisch.txt",
};
Alternativ können Referenzen benutzt werden
use constant SOURCEFILES => [qw(
/path/to/source/file1
/path/to/source/file2
)];
use constant SOME_NUMBERS => {1 => "eins", 2 => "zwei"};
Oder verwende das Pragma mehrfach:
use constant SOURCEFILE => "/path/to/source/file";
use constant DESTFILE => "/path/to/dest/filename";
VORSICHT:
Das Pragma erzeugt für jede Konstante eine Funktion, die den gewünschten Wert
zurückliefert. Aufgrund dieser Realisierung der Funktionalität kann es zu Mehrdeutigkeiten im Code kommen:
use constant SOURCEFILES => [qw(
/path/to/source/file1
/path/to/source/file2
)];
foreach (@{SOURCEFILES}) { do_something (); }
# hmm. ist hier das array @SOURCEFILES oder die funktion SOURCEFILES gemeint?
Für die Dereferenzierung der gesamten
DatenStruktur? ist in diesem Fall SOURCEFILES
explizit als Funktion zu kennzeichnen:
foreach (@{SOURCEFILES ()}) { do_something (); } # oder
foreach (@{&SOURCEFILES}) { do_something (); }
Da bei einem direkten Zugriff auf ein Element mittels der Pfeilnotation kein Qualifizierer
vor die Konstante gesetzt wird, ist dieser Zugriff eindeutig:
print SOURCEFILES->[0];
Es ist zusätzlich zu beachten, dass in diesem Falle nur die Referenz auf das Array - die ein Skalar ist - konstant ist, und nicht die Skalare, die durch das Array referenziert werden können. Im Beispiel ist folgendes möglich:
SOURCEFILES->[0] = "/path/to/source/file3";
Die einzige Konstante ist die Referenz, und diese wird nicht verändert!
Dokumentation
Das Pragma ex::constant::vars
Dieses Pragma stellt Konstanten mit Hilfe des
TieMechanismus? zur Verfügung.
Konstanten können mit Hilfe mehrerer Schreibweisen deklariert werden, den besten
Eindruck hinterließ trotzdem die explizite Kodierung:
use ex::constant::vars;
tie my $pi, 'ex::constant::vars', 4 * atan2( 1, 1 );
tie my @family, 'ex::constant::vars', qw( John Jane );
tie my %age, 'ex::constant::vars', John => 27, Jane => 'Back off!';
Das Pragma ist nicht Teil der
StandardDistribution?.
Die Implementierung ist leider ein zweischneidiges Schwert: auf der einen Seite
steht der Vorteil, dass auch Arrays und Hashes Konstanten sein können. Gegenüberliegend
ist der gewaltige Performanz Verlust, den der
TieMechanismus? mit sich bringt.
Dokumentation
- perldoc ex::constant::vars
Typeglobbing
Einem
TypeGlob? kann eine Referenz auf ein Literal zugewiesen werden. Da das Literal
konstant ist, ist der Skalar des
TypeGlob?s auch konstant.
*a = \10;
print "a enthält den wert [$a]\n";
Das Skalar $a erhält die Eigenschaft
konstant also nur durch das dahinterliegende
Literal.
Eine direkte Zuweisung eines Wertes an $a wird vom
InterPreter? zur
LaufZeit? erkannt und
das Programm abgebrochen:
*a = \10;
$a = 10; # abbruch; skalar des typeglobs ist konstant
Jedoch ist es möglich, dem
TypeGlob? einfach eine zweite Referenz auf ein Literal
zuzuweisen.
*a = \10; print "[$a]\n";
*a = \20; print "[$a]\n";
Hintergrund:
Bei ersterem zeigt der Skalareintrag des
TypeGlobs? auf ein konstantes Literal.
Da aber versucht wird, diesem konstante Literal ein neuer Wert zuzuweisen, scheitert das
Skript. Bei Letzterem wird
nicht versucht, dem konstante Literal einen anderen
Wert zuzuweisen. Stattdessen wird einfach der Skalareintrag des
TypeGlob?s - der nicht
konstant ist - auf ein anderes Literal gelegt.
Bei der Verwendung des Pragmas strict sind die verwendeten Konstanten mit dem Pragma
vars bekanntzumachen, da sonst der nicht qualifizierte Variablenzugriff mit einer entsprechenden
Meldung quittiert wird:
use strict;
use vars qw($zahl); # $zahl "qualifizieren"
*zahl = \10;
print "[$zahl]\n";
Dokumentation
- B.9, "Advanced Perl Programming", OReilly, 1997
Ergänzungen, Kommentare
StefanHanke - 12 Aug 2003 - WikiWords? eingefügt, constant.pm Inhalt gefixt.
TinaMueller 12 Aug 2003 - wikiwords?
(hab mal das <verbatim> entfernt)
hmm, wozu so viele wikiwords? z.B. Mehrdeutigkeit muss doch nicht erklärt werden,
oder hashkeys. und
use constant mit einer Hashreferenz ist AFAIK neu in 5.8.0.
für constant.pm wird keine history geführt,
allerdings kann man das aus den POD-unterschieden schließen. in perl56(1)delta steht
dazu leider auch nichts genaues ("Referenzen können nun benutzt werden" - toll).
Kommentare werden am besten in folgender Form vorgenommen, damit
sie im Inhaltsverzeichnis angezeigt werden (ohne <verbatim> natürlich!):
---### Main.??? - 14 Jul 2003 - Betreff