添加与脚本相关的 Perl 模块
我正在尝试添加模块 File-Copy-Recursive 到我的脚本,就像我已经对另一个模块所做的那样,但是当我尝试使用它时,我收到一个我无法解释的错误:
use lib "./cpan";
use Recursive qw(dircopy);
dircopy($path1, $path2);
我收到的错误是:未定义的子例程 &main::dircopy 在...调用
我不明白,该模块显然有 dircopy 函数。
im trying to add the module File-Copy-Recursive to my script as i have done with another module already, but when i try to use it i get an error i can not explain:
use lib "./cpan";
use Recursive qw(dircopy);
dircopy($path1, $path2);
the error i get is: Undefined subroutine &main::dircopy called at ...
I don't understand it, the module clearly has the function dircopy in it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如其他答案已经指出的那样,这不起作用,因为您已将包含目录中的模块位置从
File/Copy/Recursive.pm
移动到Recursive.pm
。下面是不起作用的原因:
Perl 模块(扩展名为
.pm
的文件)和 Perl 包 >(特定命名空间下的代码集合)是两个完全不同的东西。通常,我们会将一个包放入一个恰好具有相同名称的模块中,但这实际上只是为了帮助我们人类保持理智。perl
不关心其中一种方式 - 一个模块可以包含多个包,一个包可以拆分为多个文件,并且包和模块的名称对于所有<代码>perl关心。但是,仍然......仍然存在对两者使用相同名称的约定,
use
命令利用这一约定使事情变得更方便。在幕后,use Module;
表示require Module.pm; Module->import;
- 请注意,它在模块名称上调用 import,而不是模块中包含的包的名称!这就是你问题的关键。即使您已将文件移出
File/Copy/
目录,其内容仍指定package File::Copy::Recursive
,因此这就是其所有内容的位置代码结束。use Recursive
尝试调用Recursive->import
,但它不存在,因此不会导入任何内容。dircopy
函数将由File::Copy::Recursive->import
导入,但永远不会被调用。所以,是的。将
./cpan/Recursive.pm
移动到./cpan/File/Copy/Recursive.pm
,以便包名称和模块名称再次匹配并且理智被恢复。 (如果您一直在注意,您应该能够想出至少两种或三种其他方法来使其工作,但是将文件移动到./cpan
下的正确位置确实是如果您需要将File::Copy::Recursive
源保留在项目代码的子目录中,这是您的最佳选择。)As other answers have already stated, this isn't working because you've moved the module's location in the include directory from
File/Copy/Recursive.pm
to justRecursive.pm
.Here's why that doesn't work:
A Perl module (file with a
.pm
extension) and a Perl package (collection of code under a specific namespace) are two completely different things. Normally, we'll put a package into a module which happens to have the same name, but this is really just to help us humans maintain our sanity.perl
doesn't care one way or the other - one module can contain multiple packages, one package can be split across multiple files, and the names of the packages and the modules can be completely unrelated for allperl
cares.But, still... there's that convention of using the same name for both, which the
use
command exploits to make things a little more convenient. Behind the scenes,use Module;
meansrequire Module.pm; Module->import;
- note that it calls import on the module name, not the name of the package contained within the module!And that's the key to your issue. Even though you've moved the file out of the
File/Copy/
directory, its contents still specifypackage File::Copy::Recursive
, so that's where all of its code ends up.use Recursive
attempts to callRecursive->import
, which doesn't exist, so nothing gets imported. Thedircopy
function would be imported byFile::Copy::Recursive->import
, but that never gets called.So, yeah. Move
./cpan/Recursive.pm
to./cpan/File/Copy/Recursive.pm
so that the package name and the module name will match up again and sanity will be restored. (If you've been paying attention, you should be able to come up with at least two or three other ways to get this working, but moving the file to the proper place under./cpan
really is your best option if you need to keep theFile::Copy::Recursive
source in a subdirectory of your project's code.)使用 FindBin 作为相对 lib 路径:
并且您必须将整个“树”保留在 ./cpan 下,并且 use 行必须保持不变。
./cpan 目录下的文件:
Use FindBin for relative lib path:
And you have to keep the whole 'tree' under ./cpan and the use line have to remain the same.
Files under ./cpan dir:
Perl 中的模块名称不仅来自路径,还来自其
package
声明。您已将模块安装到./cpan
,但指定的包名称仍然是File::Copy::Recursive
。The module name in Perl comes not only from the path, but also from its
package
declaration. You installed the module to./cpan
, but the package name specified is stillFile::Copy::Recursive
.