2 Stimmen

Initialisiere eine konstante Variable mit Perl

Ich habe die folgende Konstante:

use constant => 7

Gibt es eine Möglichkeit, die Konstante einmalig durch eine Skalarvariable zu setzen und dann den Wert der Konstanten auf den initialisierten Wert zu setzen, d. h. so etwas wie dies:

use constant => $scalar -> dann hat die Konstante ab diesem Punkt den Wert von scalar

Irgendwelche Vorschläge?

7voto

amon Punkte 56276

Konstanten, die mit use constant erstellt werden, werden zur Kompilierungszeit verarbeitet, sodass die $scalar-Variable wahrscheinlich noch keinen Wert zugewiesen hat.

Sie können jedoch das Modul Const::Fast verwenden, um ein Skalar - nun ja - konstant zu machen:

use Const::Fast;

my $scalar = 7;
const my $constant => $scalar;
$constant = 42; # stirbt

Dies ist ohnehin vorzuziehen use constant, da es schöner ist, mit konstanten Skalaren umzugehen als mit Konstanten (die als spezielle Unterprogramme implementiert sind). Zum Beispiel kann ein konstanter Skalar in einen String interpoliert werden.

Allerdings nehmen Kompilierungszeitkonstanten an der _konstanten Faltung_soptimierung teil. Es gibt einige Fälle, in denen dies tatsächlich notwendig ist, sodass einige Verwendung von use constant erhalten bleibt.

(Wenn Sie Const::Fast nicht verwenden können, ist Readonly eine weitere Option, obwohl langsamer)

4voto

ikegami Punkte 340842

Ja, das kannst du. Natürlich musst du den Wert dem Skalar rechtzeitig zuweisen.

my $foo;
BEGIN {
   ...
   ...
   $foo = ...;
}
use constant FOO => $foo;

Du könntest auch do verwenden.

use constant FOO => do {
   ...
   ...
   ...
};

2voto

David W. Punkte 101611

Konstanten werden zur Kompilierzeit erstellt, indem eine Unterfunktion erstellt wird, die den Wert der Konstanten zurückgibt.

Zum Beispiel:

 use constant PI => 3.1415169;

Ist ähnlich wie dies:

sub PI {
    return 3.1415169;
}

Das Problem ist, dass Konstanten in verschiedenen Situationen schwer zu verwenden sind, wie zum Beispiel in regulären Ausdrücken oder in Strings mit Anführungszeichen. Es gibt eine geheime, obskure Möglichkeit, die Konstante zu interpolieren (und diese Methode funktioniert auch für andere Arten von Unterfunktionen. Sie können die Konstante innerhalb von @{[...]} einbetten):

say "Der Wert von Pi ist gleich @{[PI]}.";

# Ersetzen von Pi-Wert in Alabama: http://www.snopes.com/religion/pi.asp

$foo = s/@{[PI]}/3/g;

Hässlich, nicht wahr?

Ein anderer Weg ist die Verwendung von Typ-Globs:

*PI = \3.1415926;
our $PI;

Dies interpoliert:

say "Der Wert von Pi ist $PI."

Aber funktioniert nicht so gut mit etwas anderem als Skalaren. Sie können Arrays und Hashes definieren, aber es handelt sich nicht um Konstantenwerte.

Glücklicherweise gibt es zahlreiche Möglichkeiten, Konstanten zu definieren, die sich mehr wie Variablen verhalten. Leider gibt es auch zahlreiche Möglichkeiten, Konstanten zu definieren, die sich mehr wie Variablen verhalten, und es gibt kein Standardmodul, das Perl mitbringt. Das bedeutet, dass Sie auf jedem System, auf dem Sie Ihr Skript ausführen müssen, ein optionales CPAN-Modul installieren müssen. Wenn sich diese auf Unternehmensservern befinden, benötigen Sie wahrscheinlich jemanden, der das Modul für Sie installiert.

Außerdem, da jeder sein eigenes Lieblingskonstanten-Routine hat, werden Sie wahrscheinlich mehrere Module installieren:

Das beliebteste Modul ist Readonly:

use Readonly;

# Für Perl 5.8 und später...
Readonly my $pi => 3.1415926;

Es ist schnell und einfach, aber Readonly kann langsam sein, es sei denn, Sie installieren auch Readonly:XS, und Readonly::XS kann schwierig zu installieren sein, wenn Sie keinen C-Compiler und Make haben. Ein neueres Modul namens Const::Fast ist auch ziemlich beliebt:

use Const::Fast;
const my PI => 3.1415926;

say "Der Wert von Pi ist $pi.";

Also, das war es.

  • Sie können use constant; verwenden, das ein Standardmodul ist, sodass Sie wissen, dass es immer verfügbar ist. Es interpoliert jedoch nicht sehr einfach. Sie können die Syntax @{[...]} verwenden, aber sie ist hässlich.
  • Sie können Typ-Globs verwenden, die in nahezu jeder Version von Perl funktionieren und kein optionales Modul benötigen. Typ-Globs interpolieren, aber die Definitionssyntax ist einfach hässlich. Außerdem funktionieren sie nicht gut für Arrays und Hashes.
  • Sie können Readonly oder Const::Fast verwenden, aber Sie müssen sie über CPAN installieren, bevor Ihr Skript ausgeführt wird, was in bestimmten Situationen schwierig sein kann.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X