如何在使用之前检查是否有Perl模块?
我有以下Perl代码依赖于Term::ReadKey
来获取terminal宽度; 我的NetBSD版本缺less这个模块,所以我想在模块丢失的时候将默认的terminal宽度设置为80。
我不知道如何有条件地使用一个模块,提前知道它是否可用。 我目前的实现只是退出一个消息,说它不能findTerm::ReadKey
如果它不存在。
#/usr/pkg/bin/perl -w # Try loading Term::ReadKey use Term::ReadKey; my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize(); my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97); my $plen=$#p+1; printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p);
我在NetBSD上使用Perl 5.8.7,在CygWin上使用5.8.8你能帮我更有效地实现这个脚本吗?
这是一个不需要其他模块的简单解决scheme:
my $rc = eval { require Term::ReadKey; Term::ReadKey->import(); 1; }; if($rc) { # Term::ReadKey loaded and imported successfully ... }
请注意,下面的所有答案(我希望他们低于这个!:-)使用eval { use SomeModule }
是错误的,因为use
语句在编译时进行评估,无论它们出现在代码中的哪个位置。 所以,如果SomeModule
不可用,脚本将在编译时立即死亡。
(一个use
语句的stringeval也会起作用( eval 'use SomeModule';
),但是当require
/ import
对执行相同的事情时,在运行时没有意义parsing和编译新代码,并且在编译时进行了语法检查开机。)
最后,请注意我在这里使用eval { ... }
和$@
是简洁的。 在真正的代码中,你应该使用Try :: Tiny之类的东西,或者至less要知道它所涉及的问题 。
查看CPAN模块Module :: Load :: Conditional 。 它会做你想要的。
经典的答案(可以追溯到Perl 4,至less在“使用”之前很久)就是“require()”一个模块。 这是在脚本运行时执行的,而不是在编译时执行的,您可以testing成功或失败并做出适当的反应。
如果您需要特定版本的模块:
my $GOT_READKEY; BEGIN { eval { require Term::ReadKey; Term::ReadKey->import(); $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30; }; } # elsewhere in the code if ($GOT_READKEY) { # ... }
if (eval {require Term::ReadKey;1;} ne 1) { # if module can't load } else { Term::ReadKey->import(); }
要么
if (eval {require Term::ReadKey;1;}) { #module loaded Term::ReadKey->import(); }
注: 1;
只有在require Term::...
正确加载时才会执行。
我认为这在使用variables时不起作用。 请检查这个链接 ,说明如何使用variables
$class = 'Foo::Bar'; require $class; # $class is not a bareword #or require "Foo::Bar"; # not a bareword because of the ""
require函数将在@INC数组中寻找“Foo :: Bar”文件,并会抱怨在那里找不到“Foo :: Bar”。 在这种情况下你可以这样做:
eval "require $class";