使用qw的perl模块eval问题

时间:2013-07-24 22:29:55

标签: perl module require

如果在运行脚本时缺少模块,我试图为应用程序提供“人类可读消息”。但是,在使用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正常工作?

2 个答案:

答案 0 :(得分:1)

问题是在编译使用它的代码后加载模块。执行此操作时,不能将从模块导入的函数用作裸码。


使用SOCK_STREAM()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"); 
    }
}

答案 1 :(得分:-1)

对于use在运行时,使用string-eval,而不是block-eval,因为在编译时遇到的任何use语句都将在编译时计算

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

相关问题:

How can I check if I have a Perl module before using it?

Perl - eval not trapping "use" statement