¿Cómo puedo verificar si tengo un módulo Perl antes de usarlo?

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

No puedo descifrar cómo usar un módulo de forma condicional, 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. ¿Pueden ayudarme a implementar esto en mi script de manera más efectiva?

Aquí hay una solución escueta 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 tiempo de comstackción, independientemente de dónde aparezcan en el código. Entonces, si SomeModule no está disponible, el script morirá inmediatamente después de la comstackción.

(Una cadena eval de una sentencia de use también funcionará ( eval 'use SomeModule'; ), pero no tiene sentido analizar y comstackr código nuevo en tiempo de ejecución cuando el par require / import hace lo mismo, y se comprueba la syntax en tiempo de comstackción arrancar.)

Finalmente, tenga en cuenta que mi uso de eval { ... } y $@ aquí es sucinto para el propósito de este ejemplo. En el código real, debe usar algo como Try :: Tiny , o al menos estar al tanto de los problemas que aborda .

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 hubiera un ‘uso’) era ‘requerir ()’ un módulo. Esto se ejecuta cuando se ejecuta el script, en lugar de cuando se comstack, y puede probar si tiene éxito o no y reactjsr de manera adecuada.

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 require Term::... cargado correctamente.

Creo que no funciona cuando se usan variables. Por favor, consulte este enlace que explica cómo se puede usar con variable

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

La función require buscará el archivo “Foo :: Bar” en la matriz @INC y se quejará de que no encuentre “Foo :: Bar” allí. En este caso puedes hacer:

  eval "require $class";