为什么Perl在循环期间运行不在循环中的代码?

时间:2019-09-27 15:10:21

标签: 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问题还是工具问题?我会丢失什么吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

发生这种情况的一种方法是,如果您的循环正在写入缓冲的STDOUT,但是循环结束消息转到未缓冲的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如何使用输出缓冲的信息,请参见Suffering From Buffering,有关更多信息,请参阅经典的cas-overlay-6.0文章。