2009-09-20 12 views
14

Tengo un montón de archivos Perl que toman algunas constantes de nombre de archivo. Me gustaría definir estos en un archivo separado, algo así como un archivo de cabecera en C. ¿Cuál es la mejor/la forma más estándar de hacer esto en Perl?¿Cómo puedo definir constantes en un archivo separado en Perl?

+2

Muy cerca de duplicar a esta pregunta: http://stackoverflow.com/questions/193020/how-do-i-use-constants-from-a-perl-module – draegtun

Respuesta

16

No hay equivalente a archivos de cabecera C en Perl. Para declarar y definir constantes globales, puede usar el pragma define. No tengo experiencia con este módulo aunque la interfaz parece sensata.

Por otro lado, puede escribir un módulo donde defina constantes e importarlas en su módulo usando use. Por ejemplo:

package MyConstants; 

use strict; use warnings; 

use Exporter qw(import); 
use Const::Fast; 

our @EXPORT = qw(); 
our @EXPORT_OK = qw($X $Y); 

const our $X => 'this is X'; 
const our $Y => 'this is Y'; 

__PACKAGE__; 
__END__ 

continuación, puede utilizar este módulo de la siguiente manera:

#!/usr/bin/perl 

use strict; use warnings; 

use MyConstants qw($X); 

print "$X\n"; 
print "$MyConstants::Y\n"; 

Si estás bien con el uso de nombres de variable completo (por ejemplo $MyConstants::Y), no es necesario Exporter en absoluto.

Además, asegúrese de que las variables que exporte no sean modificables en ningún otro lado (consulte la precaución en Exporter documentos).

Por supuesto, también puede definir constantes usando constant.pm. Puede ser más rápido usar tales constantes, pero son incómodas si necesita interpolarlas en una cadena.

+3

Readonly :: Scalar también es bastante rápido si tiene Readonly :: XS instalado. Sin embargo, los hashes y las matrices son aún más lentos. –

+1

Tenga en cuenta que los documentos del exportador (http://perldoc.perl.org/Exporter.html) recomiendan que NO exporte variables, aunque le permita hacerlo. –

+2

@Robert P, IMO exportar una variable a petición es razonable, es mejor exportar uno (o más) de forma predeterminada. Si en el ejemplo anterior, esperaba usar $ X muchas, muchas veces y quería evitar la innecesaria repetición de escribir '$ MyConstants :: X' en todas partes, sería un gran beneficio. Otro caso de variables importadas es que si accidentalmente intenté usar '$ MyConstants :: x', ningún mensaje de error' strict' generaría una alerta sobre mi error, mientras que si importo '$ X' y trato de usar' $ x', strict salva el día al detectar el error. – daotoad

-2

Una forma sería escribirlos como un módulo perl, que luego puede incluir con "requerir" o "usar". Usted escribiría su archivo como esto - darle una extensión .pm (por ejemplo, myFabulousPackage.pm)

package myFabulousPackage; 

$someSetting=45; 
$otherSetting='Fish'; 

1; 

A continuación, en el script Perl, esto incluiría el archivo y después hacer referencia a $ otherSetting:

#!/usr/bin/perl 

use myFabulousPackage; 

print $myFabulousPackage::otherSetting; 

Esto es solo una vista muy simple de lo que puede hacer con un paquete/módulo, pero para lo que necesita, esta podría ser la forma más sencilla de implementarlo. De forma similar, también puede incluir subsegmentos en el paquete y hacer referencia a ellos de manera similar.

+3

Esto no va a funcionar. Las variables declaradas con mi (variables léxicas) no son accesibles a través de '$ PackageName :: varname'. Esta sintaxis solo accede a las variables en la tabla de símbolos. La mejor manera de poner variables en la tabla de símbolos es usar 'our' para declararlas. – daotoad

+1

Eso no funcionará.La declaración 'my' de las variables las hace con un alcance léxico, y por lo tanto, solo son visibles para codificar en el archivo' .pm'. Usted quiere que sean declarados con 'nuestro' en su lugar. Además, es una buena idea terminar siempre los archivos del módulo con '1;' porque si la última declaración de algún modo evalúa a un valor falso, el módulo no se cargará. – arnsholt

+0

Sí, tienes razón sobre el 'mi' ... ese soy yo escribiendo perl en piloto automático, y no comprobando dos veces mis ejemplos. Edit'd. –

7

Normalmente hacemos esto con un nombre de módulo Constantes. Algo así como:

package MyPackage::Constants; 

our $DIR = "/home/chriss"; 
our $MAX_FILES = 5; 

1; 

A continuación, se usa:

package MyPackage; 
use MyPackage::Constants; 

open(my $fh, ">", $MyPackage::Constants::DIR . "/file"); 

Si no desea hacer referencia el paquete todo el tiempo, usted podría utilizar exportador y traer a todos los símbolos que desea.

+3

¿Por qué no se definen las constantes de MyPackage en el módulo MyPackage en sí mismo, en lugar de crear un nuevo espacio de nombres? Y si hace referencia a la constante como espacio de nombres :: DIR, pierde la ventaja de la herencia, es decir, MyPackage :: Child :: Constants no puede heredar de MyPackage :: Constants y anular el valor de DIR. namespace-> DIR es mucho mejor. – Ether

+1

Este es un ejemplo simplista con fines ilustrativos. Dicho eso, no todo es OO :) –

+4

Parece una configuración, no constantes. –

5

Esto suena como configuración de configuración, que sería mejor poner en un archivo de configuración que analizar con uno de los diversos módulos de CPAN, por ejemplo Config::Any.

La configuración es datos, que IMO no debería estar en su código.

Cuestiones relacionadas