Come posso verificare se ho un modulo Perl prima di usarlo?
Domanda
Ho il seguente codice Perl che si basa su Term :: ReadKey
per ottenere la larghezza del terminale; Nella mia build NetBSD manca questo modulo, quindi desidero impostare automaticamente la larghezza del terminale su 80 quando manca il modulo.
Non riesco a capire come usare condizionalmente un modulo, sapendo in anticipo se è disponibile. La mia attuale implementazione termina con un messaggio che dice che non può trovare Term :: ReadKey
se è assente.
#/usr/pkg/bin/perl -w
# Try loading Term::ReadKey
use Term::ReadKey;
my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97);
my $plen=$#p+1;
printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p);
Sto usando Perl 5.8.7 su NetBSD e 5.8.8 su CygWin Potete aiutarmi a implementare questo nel mio script in modo più efficace?
Soluzione
Ecco una soluzione semplice che non richiede un altro modulo:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Nota che tutte le risposte qui sotto (spero siano al di sotto di questa! :-) che usano eval {use SomeModule}
sono sbagliate perché vengono valutate le istruzioni use
al momento della compilazione, indipendentemente dalla posizione nel codice. Quindi se SomeModule
non è disponibile, lo script morirà immediatamente dopo la compilazione.
(Funzionerà anche una valutazione di stringa di un'istruzione use
( eval 'use SomeModule';
), ma non ha senso analizzare e compilare il nuovo codice in fase di esecuzione quando il La coppia richiede
/ import
fa la stessa cosa ed è controllata dalla sintassi al momento della compilazione per l'avvio.)
Infine, nota che il mio uso di eval {...}
e $ @
qui è sintetico ai fini di questo esempio. Nel vero codice, dovresti usare qualcosa come Try :: Tiny , o almeno < a href = "http://search.cpan.org/dist/Try-Tiny/lib/Try/Tiny.pm#BACKGROUND" rel = "noreferrer"> fai attenzione ai problemi che affronta .
Altri suggerimenti
Guarda il modulo CPAN Modulo :: Carica :: Condizionale . Farà quello che vuoi.
La risposta classica (risalente a Perl 4, almeno molto prima che ci fosse un 'uso') era di 'richiedere ()' un modulo. Questo viene eseguito quando lo script viene eseguito, piuttosto che quando compilato, e puoi verificare il successo o il fallimento e reagire in modo appropriato.
E se richiedi una versione specifica del modulo:
my $GOT_READKEY;
BEGIN {
eval {
require Term::ReadKey;
Term::ReadKey->import();
$GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
};
}
# elsewhere in the code
if ($GOT_READKEY) {
# ...
}
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
o
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Nota: il 1;
viene eseguito solo se richiede Term :: ...
caricato correttamente.
Penso che non funzioni quando si usano le variabili. Controlla questo link che spiega come può essere utilizzato con la variabile
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
La funzione richiesta cercherà il " Foo :: Bar " file nell'array @INC e si lamenterà di non aver trovato " Foo :: Bar " Là. In questo caso puoi fare:
eval "require $class";