2012-02-15 71 views
2

IM Perl模块,试图将模块File-Copy-Recursive添加到我的剧本,我和另一个模块已经完成,但是当我尝试使用它,我得到一个错误,我无法解释:添加相对于脚本

use lib "./cpan"; 
use Recursive qw(dircopy); 
dircopy($path1, $path2); 

我得到的错误是:未定义的子程序&主:: dircopy被称为...

我不明白它,该模块显然有它的功能dircopy。

+1

你尝试使用完整的软件包名称'使用File :: Copy :: Recursive' – run 2012-02-15 10:55:05

+0

该模块不在我已安装的标准库中,我不想依赖那个。我从cpan下载了模块并将其放置在脚本所在的/ cpan文件夹中。 – 2012-02-15 10:57:58

+0

好的,所以我通过使用 File :: Copy :: Recursive :: dircopy($ path1,$ path2); 在我的代码。 我不知道为什么它只有这种方式,但。 也许有人可以对此发表评论。 – 2012-02-15 11:02:13

回答

4

正如其他答案已经指出,这是行不通的,因为您已将模块的位置从File/Copy/Recursive.pm的包含目录中移动到Recursive.pm

这里的为什么不起作用:

一个Perl 模块(用.pm扩展名的文件)和一个Perl (特定的代码命名空间下集)是两个完全不同的事情。通常情况下,我们会将一个软件包放入一个碰巧具有相同名称的模块中,但这实际上只是为了帮助我们人类保持我们的理智。 perl不关心的一种方式或其他 - 一个模块可以包含多个包,一个包可以跨多个文件分割,而包的名称和模块可以为所有关心perl完全无关。

但是,仍然有两种使用相同名称的约定,use命令利用这种约定使事情变得更方便一些。在幕后,use Module;意味着require Module.pm; Module->import; - 请注意,它调用导入的模块名称,而不是模块中包含的软件包的名称!

而这关键是你的问题。即使你已经移动的文件了File/Copy/目录,其内容仍指定package File::Copy::Recursive,因此,这就是它的所有代码的结束。 use Recursive试图呼叫​​3210,这不存在,所以没有任何东西被导入。 dircopy函数将被导入File::Copy::Recursive->import,但永远不会被调用。

所以,是的。移动./cpan/Recursive.pm./cpan/File/Copy/Recursive.pm,这样的包名和模块名称将再次匹配和理智将被恢复。 (如果你一直在关注,你应该至少有两到三种方法来实现这个功能,但是如果你需要保留这个文件,那么把这个文件移动到./cpan下的适当位置真的是最好的选择File::Copy::Recursive源代码位于项目代码的子目录中。)

2

使用FindBin相对库路径:

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

而且你必须保持整个“树”下./cpan和使用线必须保持不变。

文件下./cpan DIR:

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

嗯,我没有看到差异,因为我说它已经与另一个模块一起工作。我犯了同样的错误。 – 2012-02-15 10:41:45

1

在Perl模块名称不仅来自路径,而且从它的package声明。您所安装的模块./cpan,但指定的软件包名称仍然是File::Copy::Recursive