Pregunta

Tengo el siguiente código de Perl que se basa en Term :: ReadKey para obtener el ancho del terminal; A mi compilación de NetBSD le falta este módulo, por lo que quiero establecer de manera predeterminada el ancho del terminal a 80 cuando falta el módulo.

No puedo averiguar cómo usar condicionalmente un módulo, sabiendo de antemano si está disponible. Mi implementación actual simplemente se cierra con un mensaje que dice que no puede encontrar Term :: ReadKey si está ausente.

#/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);

Estoy usando Perl 5.8.7 en NetBSD y 5.8.8 en CygWin ¿Puedes ayudarme a implementar esto en mi script de manera más efectiva?

¿Fue útil?

Solución

Aquí hay una solución básica que no requiere otro módulo:

my $rc = eval
{
  require Term::ReadKey;
  Term::ReadKey->import();
  1;
};

if($rc)
{
  # Term::ReadKey loaded and imported successfully
  ...
}

Tenga en cuenta que todas las respuestas a continuación (¡espero que estén debajo de esta! :-) que usan eval {use SomeModule} son incorrectas porque las declaraciones de use se evalúan en el momento de la compilación, sin importar en qué parte del código aparezcan. Por lo tanto, si SomeModule no está disponible, el script morirá inmediatamente al compilarlo.

(Una cadena eval de una declaración de use también funcionará ( eval 'use SomeModule'; ), pero no tiene sentido analizar y compilar un nuevo código en tiempo de ejecución cuando el require / import par hace lo mismo, y se comprueba la sintaxis en el momento de la compilación para el arranque.)

Finalmente, tenga en cuenta que mi uso de eval {...} y $ @ aquí es sucinto para los fines de este ejemplo. En código real, debe usar algo como Try :: Tiny , o al menos < a href = "http://search.cpan.org/dist/Try-Tiny/lib/Try/Tiny.pm#BACKGROUND" rel = "noreferrer"> estar al tanto de los problemas que aborda .

Otros consejos

Consulte el módulo CPAN Module :: Load :: Conditional . Hará lo que quieras.

La respuesta clásica (que se remonta a Perl 4, al menos, mucho antes de que existiera un "uso") era "requerir ()" un módulo. Esto se ejecuta a medida que se ejecuta el script, en lugar de cuando se compila, y puede probar el éxito o el fracaso y reaccionar adecuadamente.

Y si necesita una versión específica del módulo:

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: el 1; solo se ejecuta si requiere Term :: ... cargado correctamente.

Creo que no funciona cuando se usan variables. Consulte este enlace que explica cómo se puede usar con la variable

$class = 'Foo::Bar';
        require $class;       # $class is not a bareword
    #or
        require "Foo::Bar";   # not a bareword because of the ""

La función de requerimiento buscará el " Foo :: Bar " archivo en la matriz @INC y se quejará de no encontrar " Foo :: Bar " ahí. En este caso puedes hacerlo:

 eval "require $class";
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top