如何检查perl模块是否可用?
How to check if perl module is available?
我找到了 this:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
但这不适用于在其他模块中定义的包,例如:
{
package Hi::Test;
}
my $rc = eval{ require Hi::Test };
$rc
这里是假的。
如何检查 'Hi::Test' 是否可用?
我假设该包中确实发生了一些事情,而不仅仅是一个空块。
以下代码检查该包的符号 table 中是否有任何条目。它很脏,但只要注册了 subs 或 package 变量,它就可以工作。
{
package Hi::Test;
sub foo;
}
my $rc = eval{ require Hi::Test };
if (! $rc) {
$rc = do {
no strict;
*stash = *{"Hi::Test::"};
scalar keys %stash;
}
}
print $rc;
它将打印1
。
我对此有点生疏,但我认为你的 require
无论如何都会失败 - 这个错误:
#!/usr/bin/perl
{
package Hi::Test;
sub foo {
print "bar\n";
}
}
{
package main;
require Hi::Test;
}
此错误 - 它无法找到它 @INC
(因为它不在 @INC
中)。 use
和 require
都明确告诉 perl
到 "go out and find a module file"
但您仍然可以通过以下方式调用 'foo':
Hi::Test::foo();
所以你不能用 eval
测试模块的加载,也不能检查 %INC
。
但是你可以做的是检查 %Hi::
:
use Data::Dumper;
print Dumper \%Hi::;
print Dumper \%Hi::Test::;
这给了我们:
$VAR1 = {
'Test::' => *{'Hi::Test::'}
};
$VAR1 = {
'foo' => *Hi::Test::foo
};
所以我们可以:
print "Is loaded" if defined $Hi::{'Test::'}
已更新
我找到了这条线索:
my $module = *main::;
my @sub_name = split '::', $full_name;
while( each @sub_name ) {
$module = $$module{ $sub_name[$_].'::' };
}
print "Module is available" if $module;
与 答案相比,它不会在全局存储中创建额外的变量
你想要像 defined(*Hi::Test::)
这样的东西,只是简单地提到 *Hi::Test::
就创建了包。
$ perl -E'
say defined(*Hi::Test::) ? "exists" : "doesn'\''t exist";
'
exists
通过使用符号引用,您可以避免这个问题。
$ perl -E'
{ package Hi::Test }
say defined(*{"Hi::Test::"}) ? "exists" : "doesn'\''t exist";
say defined(*{"Hi::TEST::"}) ? "exists" : "doesn'\''t exist";
'
exists
doesn't exist
将该代码放入子程序中可以使事情变得更清晰。
$ perl -E'
use strict;
use warnings;
sub test_for_package {
my ($pkg_name) = @_;
$pkg_name .= "::";
return defined(*$pkg_name);
}
{ package Hi::Test }
say test_for_package("Hi::Test") ? "exists" : "doesn'\''t exist";
say test_for_package("Hi::TEST") ? "exists" : "doesn'\''t exist";
'
exists
doesn't exist
请注意,创建包 Foo::Bar::Baz
也会创建包 Foo
和 Foo::Bar
。
我找到了 this:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
但这不适用于在其他模块中定义的包,例如:
{
package Hi::Test;
}
my $rc = eval{ require Hi::Test };
$rc
这里是假的。
如何检查 'Hi::Test' 是否可用?
我假设该包中确实发生了一些事情,而不仅仅是一个空块。
以下代码检查该包的符号 table 中是否有任何条目。它很脏,但只要注册了 subs 或 package 变量,它就可以工作。
{
package Hi::Test;
sub foo;
}
my $rc = eval{ require Hi::Test };
if (! $rc) {
$rc = do {
no strict;
*stash = *{"Hi::Test::"};
scalar keys %stash;
}
}
print $rc;
它将打印1
。
我对此有点生疏,但我认为你的 require
无论如何都会失败 - 这个错误:
#!/usr/bin/perl
{
package Hi::Test;
sub foo {
print "bar\n";
}
}
{
package main;
require Hi::Test;
}
此错误 - 它无法找到它 @INC
(因为它不在 @INC
中)。 use
和 require
都明确告诉 perl
到 "go out and find a module file"
但您仍然可以通过以下方式调用 'foo':
Hi::Test::foo();
所以你不能用 eval
测试模块的加载,也不能检查 %INC
。
但是你可以做的是检查 %Hi::
:
use Data::Dumper;
print Dumper \%Hi::;
print Dumper \%Hi::Test::;
这给了我们:
$VAR1 = {
'Test::' => *{'Hi::Test::'}
};
$VAR1 = {
'foo' => *Hi::Test::foo
};
所以我们可以:
print "Is loaded" if defined $Hi::{'Test::'}
已更新
我找到了这条线索:
my $module = *main::;
my @sub_name = split '::', $full_name;
while( each @sub_name ) {
$module = $$module{ $sub_name[$_].'::' };
}
print "Module is available" if $module;
与
你想要像 defined(*Hi::Test::)
这样的东西,只是简单地提到 *Hi::Test::
就创建了包。
$ perl -E'
say defined(*Hi::Test::) ? "exists" : "doesn'\''t exist";
'
exists
通过使用符号引用,您可以避免这个问题。
$ perl -E'
{ package Hi::Test }
say defined(*{"Hi::Test::"}) ? "exists" : "doesn'\''t exist";
say defined(*{"Hi::TEST::"}) ? "exists" : "doesn'\''t exist";
'
exists
doesn't exist
将该代码放入子程序中可以使事情变得更清晰。
$ perl -E'
use strict;
use warnings;
sub test_for_package {
my ($pkg_name) = @_;
$pkg_name .= "::";
return defined(*$pkg_name);
}
{ package Hi::Test }
say test_for_package("Hi::Test") ? "exists" : "doesn'\''t exist";
say test_for_package("Hi::TEST") ? "exists" : "doesn'\''t exist";
'
exists
doesn't exist
请注意,创建包 Foo::Bar::Baz
也会创建包 Foo
和 Foo::Bar
。