Perl关键字require给出了奇怪的结果

Perl关键字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

我有一个问题,我的程序将无限循环。我缩小了问题的范围,结果发现是关键字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::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
      文件(包括案例)的名称匹配
    因为您使用的是不区分大小写的文件系统(OSX或Windows),所以您在一定程度上没有受到影响
    use
    require
    记住他们是否已经加载了模块,但记住的是文件名,而不是模块名。当您说
    use test1
    Perl将查找
    test1.pm
    ,但它会加载
    test1.pm
    。下次当它看到
    使用test1
    时,它会看到它没有加载
    test1.pm
    并再次加载它。。。再一次。。。一次又一次

    • 将函数导出放入的变量是
      @EXPORT
      而不是
      @EXPORT
    大小写与变量名有关

    • Test1.pm
      Test2.pm
      中需要
      test.pl
      设置循环依赖项
    这就是问题所在。Perl在加载
    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