我想知道,我在perl脚本中使用的所有模块都需要在脚本的开头吗?
我很奇怪的原因是我在我的脚本中有一个位置,它“分裂”一种方式是脚本使用授权密钥连接SSH。另一种方式是脚本使用用户名和密码连接SSH。我使用模块Net::OpenSSH来做SSH。根据cpan doc,如果我想要所有用户名和密码验证,我需要IO::Pty。
我想只检查IO::Pty的要求是否触发了用户名和密码设置为登录的子程序。那可能吗?仅在触发某个子程序时加载模块?
答案 0 :(得分:3)
use IO::Pty;
行表示Perl的以下内容:
BEGIN {
require IO::Pty;
IO::Pty->import;
}
因此,首先Perl使用require加载模块(如果找不到模块将会死掉),然后调用->import
方法(如果存在)。
您可以将其转换为运行时条件,如下所示:
if (eval {require IO::Pty}) {
# IO::Pty->import;
# or use fully qualified names: IO::Pty::some_sub(...);
# in both cases, the parenthesis after the subroutine are required, since
# the import is not visible at compile time
} else {
# run other code, or throw an error with `die`
}
包导入到其他包中,而不是导入到其他范围中,因此导入将在执行它的子例程之外可见。最好一起跳过导入,只使用完全限定的名称。
答案 1 :(得分:2)
如果您只想加载模块有时,那么您可以使用require和eval来检查您是否拥有它:
$haveit = eval "require Foo::Bar";
if ($haveit) {
# do something
}
'use'例程实际上做了两件事:
require Foo::Bar;
import Foo::Bar;
问题是“使用”在执行开始时执行此操作,而不是在有条件的地方执行此操作。因此,如果您只想“有时”加载模块而不是在实际需要的地方使用require和import,请不要使用'use'。
* 编辑包括:*
我应该引用perl 'use' documentation来解释这一点。
use Module;
相当于:
BEGIN { require Module; Module->import( LIST ); }
它是“BEGIN”部分,无论脚本在哪里,都会导致它被加载,即使在另一个if()子句中也是如此。
答案 2 :(得分:1)
另请查看Module::Load。
答案 3 :(得分:0)
您不需要自己加载IO :: Pty,Net :: OpenSSH会在需要时加载它。