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()andSOMAXCONN()会将检查推迟到运行时。

或者

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在运行时,使用 string-eval,而不是 block-eval,因为use在编译时遇到的任何语句都将在编译时进行评估

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

相关问题:

在使用 Perl 模块之前如何检查它?

Perl - eval 不捕获“使用”语句

于 2013-07-24T22:43:33.950 回答