Perl - 在包层次结构中使用相关模块

时间:2015-05-05 02:46:38

标签: perl

我试图在同一名称空间内创建一些相关的类,但这些类似乎无法找到彼此。

我在名称空间Crypt::HSXKPasswd内工作。我的.pm个文件位于./lib文件夹中的正确文件路径中(Crypt::HSXKPasswd等定义了./lib/Crypt/HSXKPasswd.pm。)

在我的主模块的构造函数(Crypt::HSXKPasswd->new)中,我尝试实例化Crypt::HSXKPasswd::Dictionary::Default类型的对象。

我的测试文件位于.,其中包含以下内容:

#!/usr/bin/perl

use strict;
use warnings;
use lib './lib';
use Crypt::HSXKPasswd;

my $hsxkpasswd = Crypt::HSXKPasswd->new();

无法执行以下错误:

Can't locate Crypt::HSXKPasswd::Dictionary::Default in @INC (@INC contains: ./lib /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.2/darwin-thread-multi-2level /Library/Perl/Updates/5.18.2 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at lib/Crypt/HSXKPasswd.pm line 482.

请注意@INC包含./lib。以下head命令显示模块的.pm文件位于./lib下的正确路径中,并且它确实定义了正确的包:

$ head -1 ./lib/Crypt/HSXKPasswd/Dictionary/Default.pm 
package Crypt::HSXKPasswd::Dictionary::Default;
$

如果.pm文件存在,定义模块,并且位于相对于@INC中文件夹的正确路径中,为什么Perl没有看到它?

3 个答案:

答案 0 :(得分:1)

最有可能的是,您当前的工作目录不是您加载模块时的想象。您的某个模块中的某些内容可能正在更改当前的工作目录。例如,我可以通过具有如下所示的模块来重现该问题:

package Crypt::HSXKPasswd;

BEGIN { chdir("/"); }

use strict;
use warnings;
use Crypt::HSXKPasswd::Dictionary::Default;

1;

你的问题可能不是那么直截了当,但是你可能在链中的某个地方做一个类似的模块,无论是通过像BEGIN语句一样直接的东西还是不那么明显,就像通过在a之前更改目录一样。 require声明。鉴于你的模块在第482行失败,它可能不是加载模块的use语句(那些通常列在包的顶部),所以我倾向于chdir()启动在require之前的某个地方。

答案 1 :(得分:1)

注意错误消息中的Crypt::HSXKPasswd::Dictionary::Default - 它未转换为Crypt/HSXKPasswd/Dictionary/Default.pm,因此Perl尝试按字面加载,但失败了。

这可能发生在以下用例中:

my $foo = "Foo::Bar";
require $foo; # tries lo load literal Foo::Bar

这可以通过使用Module::Load来克服,它将自动检测您是否要加载模块或文件。

use Module::Load;

# later
my $foo = "Foo::Bar";
load $foo;  

或者可以使用字符串eval:

my $foo = "Foo::Bar";
eval "require $foo" or die $@; 

但请注意evil字符串可能很危险,因此在这种情况下请检查变量两次。

答案 2 :(得分:0)

由于我不理解的原因,仅在需要require时才从使用Crypt::HSXKPasswd::Dictionary::Default改变(仅在构造函数的某些路径中需要),而只是使用{{导入它} 1}}语句顶部的语句,解决了问题。

我认为故事的寓意可能不是试图过早地进行优化,而是为了自己的利益而不要过于聪明!

相关问题