2009-02-08 16 views
5

Ich schreibe eine App in Perl mit mehreren Modulen. Ich möchte einige globale Konstanten schreiben, die von überall her, wie dies sichtbar sein wird:Wie kann ich Konstanten in mehrere Module in Perl importieren?

#Constants.pm 
$h0 = 0; 
$scale = 20; 

und sie dann mit main:: oder Constants:: in mehreren Modulen ohne Qualifikation nutzen. Wenn ich jedoch use Constants; in mehr als einem Modul schreibe, werden sie nur in einen Namespace importiert. Gibt es einen Weg dazu?

Ich verwende das neueste ActivePerl.

Antwort

2

Sie können dies von Constants.pm an der Spitze setzen:

package main; 

In diesem Fall werden alle Variablen, die Sie definieren im main Namespace:

$main::x 

oder wenn Sie das Gefühl mutig :

package; 

In diesem Fall alle Variablen, die Sie definieren w sein krank in einem leeren Namensraum:

$::x 

Beachten Sie, dass ohne Namensraum package Verwendung wird abgeraten, und wird offenbar in einigen Versionen von Perl veraltet. Sehen Sie das Zitat unten.


Zitiert aus man perlfunc:

 

     package NAMESPACE 
     package Declares the compilation unit as being in the given 
       namespace. The scope of the package declaration is 
       from the declaration itself through the end of the 
       enclosing block, file, or eval (the same as the "my" 
       operator). All further unqualified dynamic identifiers 
       will be in this namespace. A package statement affects 
       only dynamic variables--including those you've used 
       "local" on--but not lexical variables, which are cre? 
       ated with "my". Typically it would be the first decla? 
       ration in a file to be included by the "require" or 
       "use" operator. You can switch into a package in more 
       than one place; it merely influences which symbol table 
       is used by the compiler for the rest of that block. 
       You can refer to variables and filehandles in other 
       packages by prefixing the identifier with the package 
       name and a double colon: $Package::Variable. If the 
       package name is null, the "main" package as assumed. 
       That is, $::sail is equivalent to $main::sail (as well 
       as to $main'sail, still seen in older code). 

       If NAMESPACE is omitted, then there is no current pack? 
       age, and all identifiers must be fully qualified or 
       lexicals. However, you are strongly advised not to 
       make use of this feature. Its use can cause unexpected 
       behaviour, even crashing some versions of Perl. It is 
       deprecated, and will be removed from a future release. 


Edit: Diese Frage könnte hilfreich sein, auch: How do I use constants from a Perl module?

+0

Danke. Was ich wirklich brauchte, ist das Stück über das Weglassen von "main". – Lev

+0

Ich bin gespannt, ob es tatsächlich funktioniert. Wenn dies der Fall ist, entferne ich den Haftungsausschluss oben in der Antwort. –

+1

Das setzt die Konstanten in main ::, aber jetzt müssen Sie alle Konstanten voranstellen mit: –

7

Check out Exporter und die perlmod -Handbuchseite.

5

Erzähl es niemandem Ich habe dir das gesagt, aber Perls spezielle Variablen sind überall verfügbar. Sie haben wahrscheinlich bemerkt, dass dies nicht Arbeit:

{ package Foo; 
our $global = 42; } 

{ package Bar; 
say "global is $global"; } 

Das ist, weil $global tatsächlich $Foo::global genannt wird. Sie haben auch wahrscheinlich bemerkt, dass diese „Regel“ gilt nicht für Dinge wie @INC, %ENV, $_ usw. Das ist, weil diese Variablen sind immer angenommen in main sein.

Aber eigentlich ist es mehr als nur diese Variablen. Der gesamte Glob wird in main "gezwungen". Das bedeutet, dass Sie so etwas wie dieses schreiben kann:

{ package Constants; 
    $_{PI} = 3.141592; } 

{ package Foo; 
    say "pi is $_{PI}"; } 

und es wird funktionieren.

(Gleiches gilt für $ENV, &INC, etc.)

Wenn Sie jemals in echten Code tun dies jedoch erwarten, dass jemand Sie zu ermorden :) Es ist gut zu wissen, aber nur für den Fall Sie sehen jemand anderes es tun.

2

Sie können Exporter wie folgt verwenden:

In Constants.pm:

 
#Constants.pm 
require Exporter; 
@ISA = qw(Exporter); 
@EXPORT = qw($h0 $scale); 
@EXPORT_OK = qw(myfunc); 

$h0 = 0; 
$scale = 20; 
sub myfunc {...} 

Hinweise:
* die & in &myfunc im @EXPORT Array ist optional, und es wird empfohlen, dass Sie dies nicht tun benutze es. * Diese $h0 und $scale standardmäßig exportieren, und & myfunc nur, wenn sie ausdrücklich angefordert hat (siehe unten, wie Sie angeben, welche Symbole durch den Client-Modul importiert werden)

Und dann in dem Modul, das Constants.pm importiert und will Um $h0, $scale oder &myfunc zu verwenden, fügen Sie Folgendes hinzu, um alle der Symbole zu importieren, die sich in @EXPORT in Constants.pm befinden.

 
#MyModule.pm 
use Constants qw(; 

Wenn Sie nur einige der zu importierenden Symbole verwenden:

 
#MyModule.pm 
use Constants qw($h0); 

Und schließlich, wenn Sie eines Constant.pm`s Symbole nicht importieren möchten verwenden:

 
#MyModule.pm 
use Constants(); 
7

Dieses Stück Code sollte genau das tun, was Sie wollen. Senden Sie alle Auszeichnungen an lkundrak.

package Constants; 

use base qw/Exporter/; 

use constant BOB => 666; 
use constant ALICE => 555; 

sub import { 
    no strict "refs"; 

    ${[caller]->[0].'::'}{$_} = ${__PACKAGE__."::"}{$_} 
     foreach grep { not /^(ISA|isa|BEGIN|import|Dumper)$/ } 
      keys %{__PACKAGE__."::"}; 
} 
+0

Es ist lustig, wie dies die einzige Antwort ist, die sich mit Konstanten befasst (und sogar die Frage berührt sie nicht wirklich). – Cornelius

+0

sollte dies die Antwort gewesen sein. Perfekt gearbeitet, danke! – Ishikawa91