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