Perl关键字require给出了奇怪的结果
我有一个问题,我的程序将无限循环。我缩小了问题的范围,结果发现是关键字require导致了这个问题。因此,为了理解这个问题,我编写了一个简单的helloworld程序,它与更大的程序具有完全相同的file include结构。它有一个主文件test.pl,从test2.pm调用helloWorld。test2.pm从test1.pm调用相同的例程 Test.plPerl关键字require给出了奇怪的结果,perl,Perl,我有一个问题,我的程序将无限循环。我缩小了问题的范围,结果发现是关键字require导致了这个问题。因此,为了理解这个问题,我编写了一个简单的helloworld程序,它与更大的程序具有完全相同的file include结构。它有一个主文件test.pl,从test2.pm调用helloWorld。test2.pm从test1.pm调用相同的例程 Test.pl #!/usr/bin/perl use test1; use test2; print "In test\n"; test2::hel
#!/usr/bin/perl
use test1;
use test2;
print "In test\n";
test2::helloWorld();
下午1时
#!/usr/bin/perl
package test1;
use test2;
require "test.pl";
@ISA = qw (Exporter);
@Export = qw(
helloWorld
);
sub helloWorld {
print "Hello world: Test1\n";
}
下午二时
#!/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中的“test.pl”,它只打印一次输出
Test1.pm(要求注释掉行)
这就是现在的输出:
In test
Hello world: Test1
我想如果我明白这一点,我就能解决我真正的问题。感谢您在这方面提供的帮助:)当执行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
,打印“in test”并调用test2::helloWorld
代码中有很多错误,有些是相关的,有些不是
- 包名称应与
文件(包括案例)的名称匹配.pm
use
和require
记住他们是否已经加载了模块,但记住的是文件名,而不是模块名。当您说use test1
Perl将查找test1.pm
,但它会加载test1.pm
。下次当它看到使用test1
时,它会看到它没有加载test1.pm
并再次加载它。。。再一次。。。一次又一次
- 将函数导出放入的变量是
而不是@EXPORT
@EXPORT
- 在
或Test1.pm
中需要Test2.pm
设置循环依赖项test.pl
Test1.pm
时尚未完成编译test.pl
(use
发生在编译时)Test1.pm
编译,然后被要求加载test.pl
(require
在运行时发生),它会这样做。然后,test.pl
的原始编译完成并运行其代码
您也有类似的潜在问题,因为Test1.pm
使用Test2.pm
和Test2.pm
使用Test1.pm
这让人困惑,有点像时间旅行。让我们简单一点:避免循环依赖
Test1.pm没有理由使用test.pl。一般来说,模块不应该加载程序。这是一个比我的解释好得多的解释。谢谢你的解释……它帮助了我很多。我只想再问一件事。正如您在步骤2.2中提到的,它在test“中打印
,并调用test2::helloWorld”。但是为什么它首先打印并调用函数呢?关键字require
仅用于包含文件而不执行它?这不正确吗?需要编译和运行(使用也需要编译和运行)require
只需读取文件和eval
内容,只需一次。否则像@ISA=qw(出口商)代码>不会发生。谢谢你的评论…实际上文件名和模块名是一样的。碰巧,当我输入名字时,第一个字母大写:)我肯定会将Export改为Export,因为这显然是错误的!
In test
Hello world: Test1