Почему Perl выполняет код, который не находится в цикле, во время цикла? - PullRequest
0 голосов
/ 27 сентября 2019

Я занимаюсь разработкой на 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 и выполнит эту подпрограмму.С помощью некоторых необычных кнопок в графическом интерфейсе я могу установить $ skipA и $ skipB, и это вызовет doOtherStuff () .

Если я закомментирую 2-й цикл в doOtherStuff () , то все работает нормально (1-й цикл).Но если я добавлю второй цикл, первый не завершится, а второй вступит во владение.Я поиграл с этим и заметил, что установка $ skipB вызывает проблему.

Несмотря на то, что я устанавливаю его после 1-го цикла, он все равно как-то влияет (это первый и единственный раз, когда я устанавливаю $ skipB).Итак, я думаю, что 1-й цикл должен работать до завершения, а затем переходить ко 2-му.

Может ли это быть проблемой Perl или инструментом?Могу я что-то упустить?

Спасибо!

1 Ответ

3 голосов
/ 27 сентября 2019

Один из способов это может произойти, если ваш цикл записывает в буферизованный 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 для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...