2009-02-08 15 views
5

Estoy escribiendo una aplicación en Perl con varios módulos. Quiero escribir algunas constantes globales que serán visibles desde todas partes, así:¿Cómo puedo importar constantes en múltiples módulos en Perl?

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

Y luego utilizarlos sin la calificación con main:: o Constants:: en varios módulos. Sin embargo, si escribo use Constants; en más de un módulo, solo se importarán en un espacio de nombre. ¿Hay alguna forma de evitar esto?

Estoy usando el último ActivePerl.

Respuesta

2

Usted puede poner esto en la parte superior de Constants.pm:

package main; 

En este caso, todas las variables se definen estará en el espacio de nombres main:

$main::x 

o si te sientes valiente :

package; 

En este caso, todas las variables que define w la enfermedad esté en un espacio de nombres vacío:

$::x 

Tenga en cuenta que el uso de package sin espacio de nombres no es recomendable, y al parecer será obsoleto en algunas versiones de Perl. Vea la cita a continuación.


Citando 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. 


Editar: Esta pregunta podría ser útil también: How do I use constants from a Perl module?

+0

Gracias. Lo que realmente necesitaba es la pieza sobre omisión de "principal". – Lev

+0

Tengo curiosidad si realmente funciona. Si lo hace, eliminaré el descargo de responsabilidad en la parte superior de la respuesta. –

+1

Esto pone las constantes en main ::, pero ahora tiene que prefijar todas las constantes con main :: –

7

Salida Exporter y la página perlmod hombre.

5

No le digas a nadie que te dije esto, pero las variables especiales de Perl son disponibles en todas partes. Es probable que haya notado que esto no trabajo:

{ package Foo; 
our $global = 42; } 

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

Eso es porque $global se llama en realidad $Foo::global. Usted ha también probablemente ha notado que esta "regla" no se aplica a cosas como @INC, %ENV, $_, etc Eso es porque las variables son siempre asume que están en main.

Pero en realidad, es algo más que esas variables. Todo el glob se "forzó" a main. Esto significa que puede escribir algo como esto :

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

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

y funcionará.

(Lo mismo se aplica para $ENV, &INC, etc.)

Si alguna vez se hace esto en el código real, sin embargo, esperar a alguien para asesinar a que :) Es bueno saber, sin embargo, por si acaso ves a alguien más haciéndolo.

2

Puede utilizar Exporter así:

En Constants.pm:

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

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

Notas: *
la & en &myfunc en la matriz @EXPORT es opcional, y se recomienda no lo hace usarlo * Se exportará $h0 y $scale por defecto, y & myfunc sólo si se solicita de forma explícita (véase más adelante cómo especificar los símbolos son importados por el módulo de cliente)

Y luego, en el módulo que importa y quiere Constants.pm para usar $h0, $scale o &myfunc añada lo siguiente para importar todos de los símbolos que están en @EXPORT en Constants.pm.

 
#MyModule.pm 
use Constants qw(; 

Si desea importar sólo algunos de los símbolos usar:

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

Y, por último, si usted no desea importar cualquiera de los símbolos Constant.pm`s utilizar:

 
#MyModule.pm 
use Constants(); 
7

Este fragmento de código debería hacer exactamente lo que usted desea. Envíe todas las felicitaciones al 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 curioso cómo esta es la única respuesta que trata con las constantes (e incluso la pregunta en realidad no las toca). – Cornelius

+0

esto debería haber sido la respuesta. Funcionó perfectamente, gracias! – Ishikawa91

Cuestiones relacionadas