无法在运行时加载“Cwd”(以及其他非核心模块)
Cannot load `Cwd` (and other, non-core, modules) at runtime
假设我想在运行时加载一个模块。我希望这能奏效
use warnings;
use strict;
eval {
require Cwd;
Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }
say "Dir: ", getcwd;
但根据 Bareword "getcwd" not allowed ...
,事实并非如此。
Cwd 默认导出 getcwd
。我尝试将函数名称提供给 import
,并尝试使用它的其他函数。
它使用全名 say Cwd::getcwd
,所以我认为它没有导入。
这对我尝试过的其他几个核心模块来说是有效的,例如
use warnings;
use strict;
eval {
require List::Util;
List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }
my $max = max (1, 14, 3, 26, 2);
print "Max is $max\n";
添加了注释 显然,带括号的函数调用为编译器提供了线索。但是,我认为问题仍然存在,请参阅最后的 EDIT。此外,上面模块中的 first BLOCK LIST
之类的函数不起作用。
但是,它不适用于我尝试过的一些(成熟的)非核心模块。更糟糕且更令人困惑的是,即使使用完全限定名称,它也不起作用。
我可以想象,如果在运行时使用 require
,所使用的符号(函数)在编译时是未知的,但它适用于(其他)核心模块。我认为这是在运行时加载的标准方式。
如果我在动态加载时需要使用全名,那很好,但是不一致是怎么回事?我如何在运行时加载(和使用)非核心模块?
我也试过 Module::Load::Conditional
但没用。
我错过了什么,如何在运行时加载模块? (尝试使用 5.16
和 5.10.1
。)
编辑
正如 Matt Jacob, a call with parenthesis works, getcwd()
. However, given perlsub
所述
NAME LIST;
# Parentheses optional if predeclared/imported.
这意味着导入没有起作用,为什么问题仍然存在。
此外,必须根据模块的加载方式使用不同的语法并不好。此外,我无法让非核心模块以这种方式工作,特别是那些语法如 List::MoreUtils has.
的模块
首先,这与核心模块与非核心模块无关。当解析器必须猜测特定标记是否是函数调用时,就会发生这种情况。
eval {
require Cwd;
Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }
say "Dir: ", getcwd;
在编译时,main::
符号table中没有getcwd
。没有任何提示表明它是一个函数(getcwd()
或 &getcwd
),解析器无法知道,并且 strict
抱怨。
eval {
require List::Util;
List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }
my $max = max (1, 14, 3, 26, 2);
在编译时,main::
符号table中没有max
。但是,由于您用括号调用 max
,解析器可以猜测它是稍后定义的函数,因此 strict
不会报错。
在这两种情况下,strict
检查发生在 import
被调用之前。
List::MoreUtils 是特殊的,因为函数使用原型。如果函数定义在编译时不可见,原型将被忽略。所以,你不仅要给解析器提示你正在调用一个函数,你还必须以不同的方式调用它,因为原型将被忽略:
use strict;
use warnings 'all';
use 5.010;
eval {
require List::MoreUtils;
List::MoreUtils->import('any')
};
die "Can't load List::MoreUtils: $@" if $@;
say 'found' if any( sub { $_ > 5 }, 1..9 );
假设我想在运行时加载一个模块。我希望这能奏效
use warnings;
use strict;
eval {
require Cwd;
Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }
say "Dir: ", getcwd;
但根据 Bareword "getcwd" not allowed ...
,事实并非如此。
Cwd 默认导出 getcwd
。我尝试将函数名称提供给 import
,并尝试使用它的其他函数。
它使用全名 say Cwd::getcwd
,所以我认为它没有导入。
这对我尝试过的其他几个核心模块来说是有效的,例如
use warnings;
use strict;
eval {
require List::Util;
List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }
my $max = max (1, 14, 3, 26, 2);
print "Max is $max\n";
添加了注释 显然,带括号的函数调用为编译器提供了线索。但是,我认为问题仍然存在,请参阅最后的 EDIT。此外,上面模块中的 first BLOCK LIST
之类的函数不起作用。
但是,它不适用于我尝试过的一些(成熟的)非核心模块。更糟糕且更令人困惑的是,即使使用完全限定名称,它也不起作用。
我可以想象,如果在运行时使用 require
,所使用的符号(函数)在编译时是未知的,但它适用于(其他)核心模块。我认为这是在运行时加载的标准方式。
如果我在动态加载时需要使用全名,那很好,但是不一致是怎么回事?我如何在运行时加载(和使用)非核心模块?
我也试过 Module::Load::Conditional
但没用。
我错过了什么,如何在运行时加载模块? (尝试使用 5.16
和 5.10.1
。)
编辑
正如 Matt Jacob, a call with parenthesis works, getcwd()
. However, given perlsub
NAME LIST;
# Parentheses optional if predeclared/imported.
这意味着导入没有起作用,为什么问题仍然存在。
此外,必须根据模块的加载方式使用不同的语法并不好。此外,我无法让非核心模块以这种方式工作,特别是那些语法如 List::MoreUtils has.
的模块首先,这与核心模块与非核心模块无关。当解析器必须猜测特定标记是否是函数调用时,就会发生这种情况。
eval {
require Cwd;
Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }
say "Dir: ", getcwd;
在编译时,main::
符号table中没有getcwd
。没有任何提示表明它是一个函数(getcwd()
或 &getcwd
),解析器无法知道,并且 strict
抱怨。
eval {
require List::Util;
List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }
my $max = max (1, 14, 3, 26, 2);
在编译时,main::
符号table中没有max
。但是,由于您用括号调用 max
,解析器可以猜测它是稍后定义的函数,因此 strict
不会报错。
在这两种情况下,strict
检查发生在 import
被调用之前。
List::MoreUtils 是特殊的,因为函数使用原型。如果函数定义在编译时不可见,原型将被忽略。所以,你不仅要给解析器提示你正在调用一个函数,你还必须以不同的方式调用它,因为原型将被忽略:
use strict;
use warnings 'all';
use 5.010;
eval {
require List::MoreUtils;
List::MoreUtils->import('any')
};
die "Can't load List::MoreUtils: $@" if $@;
say 'found' if any( sub { $_ > 5 }, 1..9 );