You are here: Wissensbasis Web>FaqKonstanten?>KonstantenAllgemeineVerwendung (2006-04-10)

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
  • perldoc constant


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.

StefanHanke - 14 Aug 2003 ok.
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

UtilFaqSubForm edit

Titel Konstanten: Wie verwende ich Konstanten in Perl? (vorläufige Version)
Autor kabel und perl-community
Bereich FaqTypen
Topic revision: 2006-04-10, TinaMueller
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.