0

スクリプトの実行時にモジュールが欠落している場合、アプリケーションに「人間が読めるメッセージ」を表示しようとしています。ただし、qw でモジュールをロードする際に問題が発生しました。

私は次のことを試しました:

use strict;
...
if ( ! eval { require Proc::Daemon;1; } ) {
    push (@install_packages, "Proc::Daemon"); 
} else {
    Proc::Daemon->import(qw( SOCK_STREAM SOMAXCONN ));
}

しかし、それは失敗します

Bareword "SOCK_STREAM" not allowed while "strict subs" in use at ./revmon.pl line 144.
Bareword "SOMAXCONN" not allowed while "strict subs" in use at ./revmon.pl line 144.

use を使用すると、通常のエラー メッセージが表示されるため、明らかに機能しません。

Can't locate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .)
BEGIN failed--compilation aborted at ./revmon.pl line 11.

ベアワードに * を追加しても、一度しか使用されず、使用警告とともに別のエラーがスローされるため、あまり役に立ちません。

モジュールが正常にロードされたときに BAREWORDS が正しく機能するように、これを回避する同じ方法はありますか?

4

2 に答える 2

1

問題は、モジュールを使用するコードをコンパイルした後にモジュールをロードすることです。これを行うと、モジュールからインポートされた関数をベアワードとして使用できなくなります。


SOCK_STREAM()andを使用するとSOMAXCONN()、チェックが実行時に延期されます。

または

BEGIN {
    if ( eval { require Proc::Daemon } ) {
        Proc::Daemon->import(qw( SOCK_STREAM SOMAXCONN ));
    } else {
        push(@install_packages, "Proc::Daemon"); 
        *SOCK_STREAM = sub () { die };
        *SOMAXCONN   = sub () { die };
    }
}

または、Proc::Daemon を使用して独自のモジュールに移動します

if ( eval { require Proc::Daemon } ) {
        require App::Proc::Daemon;
        $handler = App::Proc::Daemon->new();
    } else {
        push(@install_packages, "Proc::Daemon"); 
    }
}
于 2013-07-24T22:44:26.483 に答える
-1

use実行時に、block-eval ではなく string-eval を使用します。これは、コンパイル時に検出されたすべてのステートメントuseがコンパイル時に評価されるためです。

if (! eval "use Proc::Daemon qw(SOCK_STREAM SOMAXCONN); 1") { ... }

関連する質問:

Perl モジュールを使用する前に、そのモジュールがあるかどうかを確認するにはどうすればよいですか?

Perl - eval が "use" ステートメントをトラップしない

于 2013-07-24T22:43:33.950 に答える