2009-04-29 24 views
10

Estoy escribiendo un pequeño script de Perl que depende de algunos módulos que podrían estar disponibles, por lo que durante la instalación tendría que verificar si hay algo allí. Podría escribir use some::module y ver si aparece un error, pero un mensaje corto como "Necesitas instalar algún :: módulo" sería más útil para los usuarios finales.¿Cómo puedo verificar si un módulo Perl está instalado?

También podría buscar todos los directorios en @INC, pero como es Perl, tiene que haber una manera más fácil.

+1

Cómo verificar si un módulo perl está instalado no es una pregunta, es una afirmación. – cjk

Respuesta

19
perl -MSome::Module -e ';' 

Whoops, leyó mal la pregunta. Pensé que querías saber de una sola vez, sin descubrirlo de una manera recuperable. Siempre utilizo algo como esto:

sub try_load { 
    my $mod = shift; 

    eval("use $mod"); 

    if ([email protected]) { 
    #print "\[email protected] = [email protected]\n"; 
    return(0); 
    } else { 
    return(1); 
    } 
} 

cual se utiliza como esto:

$module = 'Some::Module'; 
if (try_load($module)) { 
    print "loaded\n"; 
} else { 
    print "not loaded\n"; 
} 
+1

Desea señalar aquí que la evaluación cumple una función doble: le permite verificar la existencia de un módulo arbitrario y evita que la declaración de uso se convierta en un bloque BEGIN. En resumen, si escribiera código como este pero codificado para un módulo específico, igual utilizaría la evaluación basada en cadenas. – chaos

+1

Me gustó tu respuesta, ya que quiero resolver esto desde bash, sin embargo, tengo problemas con los módulos que necesitan un argumento. p.ej. [jens @ ca60c173 (perl) p] $ perl -MPackage :: DeprecationManager -e ';' Debe proporcionar un parámetro hash -deprecations de referencia al importar Package :: DeprecationManager en -e línea 0. –

3

¿Qué tal:

die "Some::Module missing!" unless(eval{require Some::Module}); 
+1

Debe llamar a importar si va a imitar el uso y agregar una al final es una buena idea ya que la importación no es requerido para devolver un valor verdadero: eval {require Some :: Module; Algunos :: Módulo-> importar; 1}; Esto tampoco será suficiente si el módulo es de naturaleza léxica (como autobox), ya que se importará en la evaluación y luego saldrá del alcance cuando finalice la evaluación. –

1

que usar algo como esto:

BEGIN { 
    my $module_name = shift; # @ARGV 
    our $module_exp = $module_name; 
    eval "use $module_name;"; 
} 

$module_exp =~ s{::}{/}g; 
foreach my $key (grep { m/^$module_exp\./ } keys %INC) { 
    print "$key => $INC{$key}\n"; 
} 

Pero uso esto más en la forma de un shell korn f unction:

function wherperl 
{ 
    perl -M$1 <<EX_DOC 
    my \$module = '$1'; 
    \$module =~ s/::/\\//g; 

    for (keys %INC) { 
     next unless m/^\$module\./; 
     print \$_ . ' => ' . \$INC{\$_} . "\n"; 
    } 
EX_DOC 
} 
3

¿Cómo está instalando su script? Si utiliza un Makefile.PL estándar o Build.PL, enumerar las dependencias es trivial.

2

Tengo un pequeño script que enumera todos los módulos de Perl en mi sistema;

#!/usr/bin/perl 

use ExtUtils::Installed; 
my $instmod = ExtUtils::Installed->new(); 
foreach my $module ($instmod->modules()) { 
    my $version = $instmod->version($module) || "???"; 
    print "$module -- $version\n"; 
} 

Dentro de ese bucle foreach es posible que desee hacer algo similar;

my $match; 
if ($module =~ /$match/) { 
    print "Found $match: $module\n"; 
} 
1

me gustaría usar el cpan utilidad:

% cpan -D YAML 
YAML 
------------------------------------------------------------------------- 
    YAML Ain't Markup Language (tm) 
    A/AD/ADAMK/YAML-0.70.tar.gz 
    /usr/local/perls/perl-5.10.0/lib/site_perl/5.10.0/YAML.pm 
    Installed: 0.68 
    CPAN:  0.70 Not up to date 
    Ingy dot Net (INGY) 
    [email protected] 

Esto puede ser un poco lento ya que tiene que conectarse a un espejo CPAN a buscar algunos de los datos, pero también tengo un local de Espejo CPAN :)

Cuestiones relacionadas