perl – 无法在运行时加载`Cwd`(和其他非核心模块)

前端之家收集整理的这篇文章主要介绍了perl – 无法在运行时加载`Cwd`(和其他非核心模块)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
想象一下,我想在运行时加载一个模块.我希望这可行

use warnings;
use strict;

eval {
    require Cwd; 
    Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }

say "Dir: ",getcwd;

但它没有,根据Bareword“getcwd”不允许……

默认情况下,Cwd导出getcwd.我尝试提供要导入的函数名称,并尝试使用其他函数.
它使用全名,比如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";

注意添加显然,带括号的函数调用为编译器提供了线索.但是,在我看来问题仍然存在,请在最后看到编辑.此外,上述模块中的第一个BLOCK LIST等功能不起作用.

但是,它对我尝试的一些(已建立的)非核心模块不起作用.更糟糕和更令人困惑的是,即使使用完全限定的名称,它也不起作用.

我可以想象,如果在运行时使用require,则在编译时不知道所使用的符号(函数),但它适用于(其他)核心模块.我认为这是在运行时加载的标准方法.

如果我在动态加载时需要使用全名,那么很好,但是它的不一致是什么?如何在运行时加载(和使用)非核心模块?

我也尝试过使用Module :: Load :: Conditional,但它没有用.

我缺少什么,以及如何在运行时加载模块? (试过5.16和5.10.1.)

编辑

Matt Jacob所述,带括号的调用有效,getcwd().但是,鉴于perlsub

NAME LIST; # Parentheses optional if predeclared/imported.

这意味着进口不起作用,为什么仍然存在问题.

此外,必须根据模块的加载方式使用不同的语法并不好.另外,我不能让非核心模块以这种方式工作,特别是像List::MoreUtils这样的语法.

解决方法

首先,这与核心模块和非核心模块无关.当解析器必须猜测特定标记是否是函数调用时,就会发生这种情况.

eval {
    require Cwd; 
    Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }

say "Dir: ",getcwd;

在编译时,main ::符号表中没有getcwd.没有任何提示表明它是一个函数(getcwd()或& getcwd),解析器无法知道,严格抱怨.

eval { 
    require List::Util; 
    List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }

my $max = max (1,2);

在编译时,main ::符号表中没有max.但是,由于您使用括号调用max,解析器可以猜测它是稍后定义的函数,因此严格不会抱怨.

在这两种情况下,都会在调用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 );

猜你在找的Perl相关文章