2009-04-13 24 views
7

He comenzado a crear un paquete Perl que contiene una plantilla de correo electrónico predeterminada.¿Sabe un módulo Perl dónde está instalado?

El MANIFIESTO se ve algo como:

SendMyEmail.pm 
SendMyEmail/defualt_email.tt 

Actualmente sé que el módulo (y la plantilla) son - pero no el propio módulo sabe donde en disco que es? Entonces, ¿podría el módulo encontrar la plantilla predeterminada sin mi ayuda?

# This is what I would like to do. 
package SendMyEmail; 
sub new { 
    my ($self, $template) = @_; 
    $template ||= $dir_of_SendMyEmail .'/SendMyEmail/default_email.tt'; # ?? 
} 

¿Existe alguna forma mejor de incluir un texto de plantilla o un lugar mejor para colocar la plantilla?

Cualquier referencia a los módulos de CPAN que hagan algo similar sería bienvenido.

Gracias de antemano.

+0

OK, voy a votar para cerrar la cuestión. No se puede eliminar debido a las respuestas subidas de tono. –

+0

Tenga en cuenta que estos dos comentarios anteriores son de una pregunta engañosa que ahora se ha fusionado en esta, y como tales ya no son precisos. – Ether

Respuesta

9

Cada archivo Perl tiene acceso a la variable __FILE__ que le dice su ruta completa. Algo como esto debe hacer el truco:

my $DEFAULT_TEMPLATE; 
BEGIN { 
    $DEFAULT_TEMPLATE = __FILE__; 
    $DEFAULT_TEMPLATE =~ s,\.pm$,/default_email.tt,; 
} 

Sin embargo, si lo que quieres es agrupar archivos 'datos' con sus módulos entonces miren File::ShareDir que proporciona una manera de hacer eso.

+0

__FILE__ se describe en perldata. http://perldoc.perl.org/perldata.html – CoffeeMonster

2

reescrito para reflejar lo que he aprendido en los comentarios:

  • Encuentra el Camino del Módulo

    package FooBar; 
    
    use File::Spec; 
    sub location { 
    return File::Spec->rel2abs(__FILE__); 
    } 
    
  • ¿Dónde poner la plantilla:

    Desde una plantilla, se lo más probable es que sea editable, tal vez incluso por alguien que trabaje en la red, yo str ongly aconsejo ponerlo en un directorio donde el "código" contenido en la plantilla no se puede ejecutar.

    Imagínese que alguien llamando: http://your.home.net/cgi-bin/default_email.tt

+0

FindBin solo le dará la ubicación del script de Perl que se inició (el archivo .pl), no la ubicación del archivo que invoca FindBin. – potyl

+0

¡Buen punto! ¡Obviamente no leí la pregunta lo suficientemente cerca! – lexu

+0

Desafortunadamente, __FILE__ no devuelve la ruta completa tampoco, 'solo' la ruta relativa al script, parece. El libro de camellos (copia antigua) tampoco es específico. – lexu

3

Perl también registra la ubicación del archivo en la variable% INC. Puede usar eso cuando __FILE__ no está disponible. Consulte la documentación en perlvar para más detalles.

5

Puede usar %INC hash si el módulo ya está cargado. Por ejemplo:

## load the module 
use Data::Dumper; 

## output full path to Data::Dumper module loaded 
print $INC{'Data/Dumper.pm'}; 

## see which module was loaded (if you have multiple folders with same modules) 
print Dumper(\%INC); 
1

Usted puede utilizar el token __FILE__ para obtener el nombre (incluida la ruta) del archivo actual. Si desea conocer la ruta a un módulo diferente (uno que ya está cargado) verifique el contenido del hash %INC.

7

El uso de% INC puede ser engañoso en los casos en que el archivo no coincide exactamente con el nombre del paquete. (Esto es un antipatrón, pero sucede, a veces por razones justificables). Si desea localizar archivos, el práctico token __FILE__ es su mejor opción.Ejemplo módulo que puede situarse:

package Foo::Bar; 

use Cwd qw(abs_path); 
use File::Basename qw(dirname); 

sub module_dir { abs_path(dirname(__FILE__)) } 

1; 

Uso:

use Foo::Bar; 

print Foo::Bar->module_dir, "\n"; 
+0

Esto no funcionará para los módulos que no puede controlar –

+2

El sub ejemplo en la pregunta se llama "findmyself" y usa '__PACKAGE__', así que creo que el control de el módulo es una suposición segura. –

1

utilizo este alias de bash para encontrar la ubicación de un módulo (por ejemplo, para observar su aplicación o para introducirse en algunas declaraciones de impresión de depuración):

perlwhere() { 
    perl -wle'eval "require $ARGV[0]" or die; ($mod = $ARGV[0]) =~ s|::|/|g; print $INC{"${mod}.pm"}' $1 
} 
 
$ perlwhere Test::More 
/usr/lib/perl5/5.8.8/Test/More.pm 
Cuestiones relacionadas