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?

È stato utile?

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";
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top