我遇到了一个问题,我的程序无限循环。我缩小了问题的范围,结果发现关键字导致了这种情况。因此,为了理解这个问题,我写了一个简单的hello world程序,它具有确切的文件包含结构作为更大的程序。它有一个主文件 test.pl ,它从 test2.pm 调用helloWorld。 test2.pm从 test1.pm 调用相同的例程。
Test.pl
#!/usr/bin/perl
use test1;
use test2;
print "In test\n";
test2::helloWorld();
Test1.pm
#!/usr/bin/perl
package test1;
use test2;
require "test.pl";
@ISA = qw (Exporter);
@Export = qw(
helloWorld
);
sub helloWorld {
print "Hello world: Test1\n";
}
Test2.pm:
#!/usr/bin/perl
package test2;
use test1;
@ISA = qw (Exporter);
@Export = qw(
helloWorld
);
sub helloWorld {
test1::helloWorld();
}
这是该程序的输出:
In test
Hello world: Test1
In test
Hello world: Test1
我希望了解为什么它会两次打印输出?如果我发表评论 从test1.pm #require“test.pl”,它只输出一次输出。
Test1.pm(需要注释掉的行)
#!/usr/bin/perl
package test1;
use test2;
#require "test.pl";
@ISA = qw (Exporter);
@Export = qw(
helloWorld
);
sub helloWorld {
print "Hello world: Test1\n";
}
这就是现在的输出:
In test
Hello world: Test1
我想如果我明白这一点,我就能解决我的真正问题。感谢您在这方面的任何帮助:)
答案 0 :(得分:4)
执行perl脚本时,到目前为止通过require
和use
加载的文件都保存在%INC
哈希中,以防止代码执行多次,并且防止无限的相互递归。但是,您从其导入的某个模块导入主脚本,因此它将在导入过程中运行一次,并再次作为脚本运行。以下是加载和执行文件的顺序:
test.pl
运行并看到它需要加载test1.pm
。
test1.pm
已加载,它看到需要加载test2.pm
test2.pm
已加载,并且它看到需要加载test1.pm
,但test1.pm
已加载,因此会继续。test2::helloWorld
已定义,test2.pm
返回。test1
,它现在看到需要加载test.pl
。
test.pl
,我们尝试加载test1.pm
和test2.pm
,但它们已经通过require
加载。test2::helloWorld
test1.pm
,定义test1::helloWorld
test.pl
,打印"在测试"并致电test2::helloWorld
。答案 1 :(得分:3)
你的代码中有很多错误,有些错误则不同。
.pm
文件的名称相匹配,包括案例。由于您使用的是不区分大小写的文件系统(OS X或Windows),因此您可以轻松逃脱。 use
和require
记住他们是否已加载模块,但他们记住文件名,而不是模块名称。当你说use test1
Perl会寻找test1.pm
时,却会加载Test1.pm
。下次看到use test1
时,它会看到它未加载test1.pm
并再次加载......再次加载......再次加载。
@EXPORT
而不是@Export
。案例涉及变量名称。
test.pl
中的Test1.pm
或Test2.pm
设置循环依赖。这就是问题所在。 Perl在加载test.pl
时(Test1.pm
在编译时发生)尚未完成编译use
。 Test1.pm
编译然后被要求加载test.pl
(运行时发生require
)。然后test.pl
的原始编译完成并运行其代码。
您有类似的潜在问题,因为Test1.pm
使用Test2.pm
而Test2.pm
使用Test1.pm
。
这令人困惑,有点像时间旅行。让我们简单一点:避免循环依赖。
Test1.pm没有理由使用test.pl.通常,模块永远不应该加载程序。