2012-06-22 6 views
9

Tengo un problema de Perl: importación de símbolos, dependiendo de los elementos de ruta en @INC y la instrucción use.perl: Exportador no funciona con elementos de ruta en la instrucción `use`

Si pongo la ruta completa en @INC, la importación funciona. Si una parte de la ruta se encuentra en la declaración use se ejecuta el módulo de importación, pero la importación tiene que ser hecho de manera explícita:

######################################## 
# @INC has: "D:/plu/lib/" 

#------------------------------------------------ 
# Exporting file is here: "D:/plu/lib/impex/ex.pm" 
# 
use strict; 
use warnings; 
package ex; 

use Exporter; 
our @ISA = 'Exporter'; 
our @EXPORT = qw(fnQuark); 

sub fnQuark { print "functional quark\n"; } 

print "Executing module 'ex'\n"; 
1; 

#------------------------------------------------ 
# Importing file, example 1, is here: "D:/plu/lib/impex/imp.pl" 
# 
use strict; 
use warnings; 
package imp; 

use impex::ex; 

ex->import(@ex::EXPORT); # removing this line makes fnQuark unavailable! 
           # Why is this necessary, 'ex.pm' being an Exporter? 
fnQuark(); 

#------------------------------------------------ 
# Importing file, example 2, is here: "D:/plu/lib/impex/imp2.pl" 
# 
use strict; 
use warnings; 
package imp2; 

use lib 'D:/plu/lib/impex'; 
use ex; 

fnQuark();     # works without explicit import 
#------------------------------------------------- 

¿Cuál es mi error?

Respuesta

10

Cuando dice

use Foo; 

esto es equivalente a:

BEGIN { 
    require 'Foo.pm'; 
    Foo->import; 
}; 

que haya definido el paquete en su ex.pm ser identificado ex, por lo que cuando use impex::ex, Perl hace una implícita impex::ex->import . Pero no hay ningún paquete llamado impex::ex, por lo que tiene que hacer la importación manualmente desde ex para obtener sus símbolos.

La forma correcta de hacerlo es colocar los módulos bajo un directorio existente en @INC y nombrar el paquete después del nombre de ruta completo relativo al directorio @INC. Por lo tanto, su impex/ex.pm debe comenzar con package impex::ex; y así es como debería hacerlo use.

Si le preocupa que los nombres de los paquetes sean largos y poco manejables, eche un vistazo a aliased.

+1

Gracias por la respuesta rápida. Pero no entiendo por qué no tuve este problema antes. Tengo tantos módulos, e. gramo. 'FotoArchive.pm' en lib/Foto, con el nombre del paquete FotoArchive y Foto no en la ruta @INC. ¿Por qué eso no causa los mismos problemas cuando los invoco a través de Foto :: FotoArchive? - Ah, empiezo a ver, porque no exportan nada. ¡Así que me libré de mi error durante tanto tiempo! ¡Gracias! – Sadko

Cuestiones relacionadas