我试图将Carton安装到我的项目的本地目录中,得到了错误:
--> Working on Test::Deep
Fetching...
...
t/isa.t ..................... Can't locate Mojo/Base.pm in @INC (you may need to install the Mojo::Base module) (@INC contains: CODE(0x557913d006d0) t/lib /home/kes/.cpanm/work/1626520042.29670/Test-Deep-1.130/blib/lib /home/kes/.cpanm/work/1626520042.29670/Test-Deep-1.130/blib/arch /home/kes/work/projects/tucha/monkeyman/local/lib/perl5/x86_64-linux /home/kes/work/projects/tucha/monkeyman/local/lib/perl5 /home/kes/work/projects/tucha/monkeyman/lib /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/site_perl/5.35.1/x86_64-linux /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/site_perl/5.35.1 /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/5.35.1/x86_64-linux /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/5.35.1 CODE(0x557913d00670) .) at /home/kes/work/projects/tucha/monkeyman/lib/A.pm line 2.
BEGIN failed--compilation aborted at /home/kes/work/projects/tucha/monkeyman/lib/A.pm line 2.
Compilation failed in require at /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/5.35.1/base.pm line 138.
...propagated at /home/kes/perl5/perlbrew/perls/perl-5.35.1/lib/5.35.1/base.pm line 160.
BEGIN failed--compilation aborted at t/isa.t line 133.发生此错误是因为我的应用程序有A模块,但是t/isa.t已经定义了自己的package A,该package A已经加载到内存中。
# Test::Deep:t/isa.t:120
package A;
use Test::Deep;
@A::ISA = qw( Test::Deep );
{
::ok(A->isa("Test::Deep"), "U::isa says yes");
::ok(! A->isa("Test"), "U::isa says yes");
}
{
package C;
use base 'A'; # <<<< this cause error
}但是,为什么use base 'A'试图在package A已经加载到内存时从磁盘重新加载包A呢?
perl -v 5.35.1
发布于 2021-07-17 12:25:31
您正在体验包和模块之间的差异。包是一个命名空间。模块是一个文件。很容易混淆它们,因为按照约定,Foo::Bar::Baz命名空间的定义将在文件Foo/Bar/Baz.pm中。
当你写:
use Foo::Bar::Baz;Perl将其解释为两个指令:
如果没有加载
Foo/Bar/Baz.pm。Foo::Bar::Baz命名空间上的方法import。( use base 'Foo::Bar::Baz'也做了类似的事情,除了#2之外,它在继承方面做了一些奇怪的事情。)
因此,在您的例子中,当您执行use base 'A'时,Perl将执行#1,除非文件A.pm已经加载。是的,您已经在A命名空间中定义了一些内容,但这并不重要。
给你一些不同的解决方案。
让Perl以为A.pm已经加载了
在use base 'A'之前添加这一行将使Perl以为A.pm已经加载。
BEGIN { $INC{'A.pm'} = __FILE__ };使用父级
这样做,而不是use base 'A'
use parent '-norequire', 'A';parent是更现代的base版本,有一个跳过步骤1的-norequire选项。
不要使用基或父
所有这些模块都在为您设置@ISA变量。你可以自己去做。
{
package C;
our @ISA = 'A';
}https://stackoverflow.com/questions/68420020
复制相似问题