添加与脚本相关的 Perl 模块

发布于 2025-01-06 12:30:49 字数 380 浏览 0 评论 0原文

我正在尝试添加模块 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眸中客 2025-01-13 12:30:49

正如其他答案已经指出的那样,这不起作用,因为您已将包含目录中的模块位置从 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 just Recursive.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 all perl 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; means require 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 specify package File::Copy::Recursive, so that's where all of its code ends up. use Recursive attempts to call Recursive->import, which doesn't exist, so nothing gets imported. The dircopy function would be imported by File::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 the File::Copy::Recursive source in a subdirectory of your project's code.)

甩你一脸翔 2025-01-13 12:30:49

使用 FindBin 作为相对 lib 路径:

use FindBin;
use lib "$FindBin::Bin/./cpan";
use File::Copy::Recursive;

并且您必须将整个“树”保留在 ./cpan 下,并且 use 行必须保持不变。

./cpan 目录下的文件:

 find ./cpan/
 ./cpan/File/Copy/Recursive.pm

Use FindBin for relative lib path:

use FindBin;
use lib "$FindBin::Bin/./cpan";
use File::Copy::Recursive;

And you have to keep the whole 'tree' under ./cpan and the use line have to remain the same.

Files under ./cpan dir:

 find ./cpan/
 ./cpan/File/Copy/Recursive.pm
影子的影子 2025-01-13 12:30:49

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 still File::Copy::Recursive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文