首页 > 解决方案 > 为什么 Perl 在循环期间运行不在循环中的代码?

问题描述

我是第一次在 Perl 中开发,我正在添加一个非常大的现有工具。所以,我提前为任何事情道歉。

下面的代码是一个 Perl 测试脚本:

SC "SA Text Here";
SC "SB Text Here";  # SA not important
SC "SB Text Here";

SC "SA Text Here";
SC "SB Text Here";
SC "SB Text Here";

编码:

my $skipA = -1;   
my $skipB = -1;    
my $skipC = -1;    
my $currentA = 0;
my $currentB = 0;
my $currentC = 0;

# Other subs set $skipA, $skipB, $skipC, but how they are set is not important. If set to anything other than -1, they should be a positive integer.

sub SC($)
{
  # Do some stuff and set $verb

  if( $verb eq "SA" )
  {
    # Starting
    $currentA++;
    $currentB = 0;
    $currentC = 0;

    # Check mode
    if( $sxMode eq "X" )
    {
      if( ( $skipA> -1 && $currentA > $skipA ) || $skipB > -1 )
      {
        logstatus 0, "DONE";
        $skipA= -1;
        $skipB = -1;
        $skipC = -1;
      }
    }
    $skipA = -1;
    $skipB = -1;
  }

  if( $verb eq "SB" )
  {
    # Starting
    $currentB++;
    $currentC = 0;

    # Check mode
    if( $sxMode eq "X" )
    {
      if( $skipB> -1 && $currentB > $skipB )
      {
        logstatus 0, "DONE";
        $skipA= -1;
        $skipB = -1;
        $skipC = -1;
      }
    }
    $skipC = -1;
  }
}

# Should execute the first loop, finish, then start the second loop
sub doOtherStuff()
{
  #Do other stuff here

  # This loop should take me to the $i-th SA in the test script
  for( my $i = 1; $i <= 10; $i++ )
  {
    $skipA = $currentA;
    print "THIS IS I $i\n";
    doSomething();  # Not important
  }

  # This loop should take me to the $j-th SB of the $i-th SA in the test script
  for( my $j = 1; $j <= 10; $j++ )
  {
    $skipB = $currentB;
    print "THIS IS J $j\n";
    doSomething();  # Not important
  }

示例:如果我从 1.1 开始(currentA = 1,currentB = 1)并且我想跳到 2.3,我将到达 1.3。预期输出与实际输出:

Actual Output               Expected Output
THIS IS I 1                 THIS IS I 1
THIS IS J 1                 THIS IS I 2
THIS IS J 2                 THIS IS J 1
THIS IS J 3                 THIS IS J 2
                            THIS IS J 3

当 Perl 测试脚本运行时,它将看到 SC 并执行该子程序。借助 GUI 上一些精美的按钮,我可以设置 $skipA 和 $skipB,这将触发doOtherStuff()

如果我注释掉doOtherStuff()中的第二个循环,那么一切正常(第一个循环)。但是,如果我添加第二个循环,第一个将不会完成,第二个将接管。我玩过它,我注意到设置 $skipB 导致了这个问题。

即使我在第一个循环之后设置它,它仍然以某种方式影响它(这是我第一次也是唯一一次设置 $skipB )。所以,我认为第一个循环应该一直运行到完成,然后继续进行第二个循环。

这可能是 Perl 问题还是工具问题?我会错过什么吗?

谢谢!

标签: perl

解决方案


发生这种情况的一种方法是,如果您的循环正在写入缓冲STDOUT但您的循环结束消息转到 unbuffered STDERR

(*STDOUT)->autoflush(0);   # use buffered STDOUT

for $i (1 .. 10) {
    if ($i == 1) {
        print STDERR "$i ";
    } else {
        print STDOUT "$i ";
    }
}
print STDERR "Done with the loop. ";

输出:

1 Done with the loop. 2 3 4 5 6 7 8 9 10

输出缓冲是 Perl(以及在许多其他地方)为了提高效率而使用的一种方案。在将输出添加到缓冲区和缓冲区数据实际写入输出设备之间可能存在延迟。

有关perldoc -v '$|'Perl 如何使用输出缓冲的信息,请参阅参考资料,有关更多信息,请参阅经典的遭受缓冲的文章。


推荐阅读