Frage

Ich habe folgendes Perl-Code, der auf Term::ReadKey verlässt sich die Anschlussbreite zu erhalten; Mein NetBSD Build dieses Modul fehlt, so möchte ich die Breite des Terminals 80 auf Default, wenn das Modul fehlt.

Ich kann nicht herausfinden, wie bedingt ein Modul verwenden, um, vor der Zeit, zu wissen, ob es verfügbar ist. Meine aktuelle Implementierung beendet nur mit einer Meldung, die besagt es nicht Term::ReadKey finden können, wenn sie nicht vorhanden ist.

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

Ich bin mit Perl 5.8.7 auf NetBSD und 5.8.8 auf CygWin Können Sie mir das in meinem Skript effektiver helfen implementieren?

War es hilfreich?

Lösung

Hier ist eine Barebone-Lösung, die nicht ein anderes Modul benötigt:

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

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

Beachten Sie, dass alle Antworten unten (ich hoffe, dass sie unter diesem bist! :-), dass die Verwendung eval { use SomeModule } falsch sind, weil use Aussagen zum Zeitpunkt der Kompilierung ausgewertet werden, unabhängig davon, wo in dem Code, den sie erscheinen. Also, wenn SomeModule nicht verfügbar ist, wird das Skript stirbt sofort nach kompilieren.

(A String eval eine use Anweisung funktioniert auch (eval 'use SomeModule';), aber es hat keinen Sinn, das Parsen und die Erstellung neuer Code zur Laufzeit, wenn das require / import Paar macht das Gleiche, und ist Syntax-geprüft bei der Kompilierung zu booten ).

Schließlich ist zu beachten, dass meine Verwendung von eval { ... } und hier $@ zum Zweck dieses Beispiels prägnant ist. In echten Code, sollten Sie so etwas wie Versuchen :: Tiny oder zumindest verwenden < a href = "http://search.cpan.org/dist/Try-Tiny/lib/Try/Tiny.pm#BACKGROUND" rel = "noreferrer"> beachten sie die Fragen es Adressen.

Andere Tipps

das CPAN Check out Modul Module :: Load :: Conditional . Es wird tun, was Sie wollen.

Die klassische Antwort (zurückgehend auf Perl 4, zumindest, lange bevor es eine ‚Verwendung‘) war zu ‚require ()‘ ein Modul. Dies wird ausgeführt, wie das Skript ausgeführt wird, und nicht, wenn kompiliert, und Sie können für Erfolg oder Misserfolg testen und entsprechend reagieren.

Und wenn Sie benötigen eine bestimmte Version des Moduls:

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();
}

oder

if  (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}

. Hinweis: die 1; führt nur dann, wenn require Term::... richtig geladen

Ich denke, es funktioniert nicht, wenn Variablen. Bitte überprüfen Sie diesen Link , die erklärt, wie es mit Variable verwendet werden kann

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

Die Funktion erfordert sucht nach der „Foo :: Bar“ Datei im @INC Array und beschweren sich über nicht „Foo :: Bar“ dort zu finden. In diesem Fall können Sie tun:

 eval "require $class";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top