2009-09-23 7 views
10

No sé cómo hacer una cosa en Perl y siento que estoy haciendo algo fundamentalmente incorrecto.¿Cómo cargo un archivo en relación con una ruta de módulo?

Estoy haciendo un proyecto más grande, así que dividí la tarea en diferentes módulos. Puse los módulos en el directorio del proyecto, en el subdirectorio "modules /", y agregué este directorio a PERL5LIB y PERLLIB.

Todos estos módulos usan alguna configuración, guardada en un archivo externo en el directorio principal del proyecto - "../configure.yaml" si lo mira desde la perspectiva del archivo del módulo.

Pero, ahora, cuando uso el módulo a través de "usar", todas las rutas relativas en el módulo se toman como del directorio actual del script usando estos módulos, no desde el directorio del módulo mismo. Ni siquiera cuando uso FindBin ni nada.

¿Cómo cargo un archivo, relativo a la ruta del módulo? ¿Es eso posible/aconsejable?

Respuesta

13

Tiendas Perl donde se cargan los módulos en el hash% INC. Puede cargar cosas relativas a que:

package Module::Foo; 
use File::Spec; 
use strict; 
use warnings; 

my ($volume, $directory) = File::Spec->splitpath($INC{'Module/Foo.pm'}); 
my $config_file = File::Spec->catpath($volume, $directory, '../configure.yaml'); 

% de teclas INC se basan en una traducción estricta de :: a/con .pm anexa, incluso en de Windows, VMS, etc.

Tenga en cuenta que la los valores en% INC pueden ser relativos al directorio actual si coloca directorios relativos en @INC, así que tenga cuidado si cambia directorios entre require/use y checking% INC.

+0

y gracias también. –

-3

Cambie su llamada use Module al require Module (o require Module; Module->import(LIST)). Luego, use el depurador para recorrer el proceso de carga del módulo y ver de dónde cree Perl que está cargando los archivos.

+2

así, no creo que hay un error en mi programa - apenas no sé, cómo escribirlo :) si sólo escriba, por ejemplo, LoadFile ("../ configure.yaml"); en el módulo, y uso ese módulo en un script que está en otro lugar, Perl simplemente lo usa como una ruta relativa desde el archivo de script, NO el archivo del módulo. Requerir o eliminar errores realmente no ayuda, SÉ dónde está el problema, simplemente no sé qué hacer con él –

8

La tabla global %INC contiene una entrada para cada módulo que tenga use 'd o require' d, asociado con el lugar donde Perl encontró ese módulo.

use YAML; 
print $INC{"YAML.pm"}; 

>> /usr/lib/perl5/site_perl/5.8/YAML.pm 

¿Te resulta útil?

+0

Sí, lo es ... gracias :) –

9

Existe un módulo llamado File::ShareDir que existe para resolver este problema. Estaba en el camino correcto al intentar FindBin, pero FindBin siempre encuentra el programa en ejecución, no el módulo que lo está usando. ShareDir hace algo bastante similar a la solución de ysth, excepto que está envuelto en una interfaz agradable.

El uso es tan simple como

my $filename = File::ShareDir::module_file(__PACKAGE__, 
    'my/data.txt'); 
# and then open $filename or whatever else. 

o

my $dirname = File::ShareDir::module_dir(__PACKAGE__); 
# Play ball! 
Cuestiones relacionadas