无法在运行时加载`Cwd`(和其他非核心模块) [英] Cannot load `Cwd` (and other, non-core, modules) at runtime

查看:90
本文介绍了无法在运行时加载`Cwd`(和其他非核心模块)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我想在运行时加载一个模块。我希望这个工作

Imagine I want to load a module at runtime. I expected this to work

use warnings;
use strict;

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

say "Dir: ", getcwd;

但不是,每不允许使用Barewordgetcwd..

Cwd 导出 getcwd 默认情况下。我尝试将函数名称提供给 import ,我尝试了其他函数。
它使用全名,说Cwd :: getcwd ,所以我认为它不是导入。

The Cwd exports getcwd by default. I tried giving the function name(s) to import and I tried with its other functions. It works with the full name, say Cwd::getcwd, so I'd think that it isn't importing.

这适用于我尝试的其他一些核心模块,例如

This works as attempted for a few other core modules that I tried, for example

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 。此外,上述模块中的第一个BLOCK LIST 等函数不起作用。

NOTE added   Apparently, function calls with parenthesis give a clue to the compiler. However, in my opinion the question remains, please see EDIT at the end. In addition, a function like first BLOCK LIST from the module above does not work.

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

However, it does not work for a few (well established) non-core modules that I tried. Worse and more confusingly, it does not work even with the fully qualified names.

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

I can imagine that the symbol (function) used is not known at compile time if require is used at runtime, but it works for (other) core modules. I thought that this was a standard way to load at runtime.

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

If I need to use full names when loading dynamically then fine, but what is it with the inconsistency? And how do I load (and use) non-core modules at runtime?

我也试过模块: :Load :: Conditional 并且它不起作用。

I also tried with Module::Load::Conditional and it did not work.

我缺少什么,以及如何在运行时加载模块? &NBSP; (尝试 5.16 5.10.1 。)

What am I missing, and how does one load modules at runtime?   (Tried with 5.16 and 5.10.1.)

编辑

Matt Jacob ,带括号的调用, getcwd()。但是,给定 perlsub

As noted by Matt Jacob, a call with parenthesis works, getcwd(). However, given perlsub


名称列表; #如果预先声明/导入,则括号可选。

NAME LIST; # Parentheses optional if predeclared/imported.

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

this implies that the import didn't work and the question of why remains.

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

Besides, having to use varied syntax based on how the module is loaded is not good. Also, I cannot get non-core modules to work this way, specially the ones with syntax like List::MoreUtils has.

推荐答案

首先,这没什么做核心模块和非核心模块。当解析器必须猜测特定令牌是否是函数调用时,就会发生这种情况。

First, this has nothing to do with core vs. non-core modules. It happens when the parser has to guess whether a particular token is a function call.

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

say "Dir: ", getcwd;

在编译时,没有 getcwd main :: 符号表中。没有任何提示表明它是一个函数( getcwd()& getcwd ),解析器没办法要知道,严格投诉。

At compile time, there is no getcwd in the main:: symbol table. Without any hints to indicate that it's a function (getcwd() or &getcwd), the parser has no way to know, and strict complains.

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

my $max = max (1, 14, 3, 26, 2);

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

At compile time, there is no max in the main:: symbol table. However, since you call max with parentheses, the parser can guess that it's a function that will be defined later, so strict doesn't complain.

在这两种情况下,严格检查发生在导入之前永远被调用。

In both cases, the strict check happens before import is ever called.

List :: MoreUtils是特殊的,因为函数使用原型。如果函数定义在编译时不可见,则忽略原型。所以,你不仅必须给解析器一个提示你正在调用一个函数,你还必须以不同方式调用它,因为原型将被忽略:

List::MoreUtils is special because the functions use prototypes. Prototypes are ignored if the function definition is not visible at compile time. So, not only do you have to give the parser a hint that you're calling a function, you also have to call it differently since the prototype will be ignored:

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 );

这篇关于无法在运行时加载`Cwd`(和其他非核心模块)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆