3

私が持っている質問は少し抽象的ですが、私の声明で明確にしようとします. (これは一種の「ラバーダック効果」の投稿なので、入力するだけでどこかにたどり着くことができれば幸いです。ただし、返信は素晴らしいでしょう!)

私は (少なくともまだ) 変更できない古い fortran コードを持っているので、そのぎこちない出力で立ち往生しています。

私は perl を使用して、注釈が不十分な ASCII 出力ファイルを後処理しています。「ああ、パーフェクトなパーフェクト」とあなたは言います。はい、そうです。しかし、私が思いついたのはかなりひどいコーディングである、と最近結論付けました。

私の質問は、人々がそのような目的を達成するために使用することを好む一般的な構造についてです。私が言ったように、私は自分が選んだものに満足していません。

私がたどり着いた構造の疑似コードは次のとおりです。

flag1 = 0;
flag2 = 0;
while (<INPUT>) {
   if (cond1) {
      do something [like parse and set a header];
      flag1 = 1;
   } else {
     next;
   }
   if (flag1 == 1 && cond2) {
      do something else [like process a block of data];
   } else {
     next;
   }
}

上記のコードの目的は、不十分に分割された ascii ファイルに対応するブロックに処理を分割できるようにすることです。ファイルには「タグ」によるものはあまりないため、条件 ( cond1cond2など) は次のとおりです。関与。フラグを設定する目的は、他の理由の中でもとりわけ、ファイルを通じてコードの進行状況を追跡することです。

より良い構造は

while (<INPUT>) {
   do stuff;
}

while (<INPUT>) {
   do other stuff;
}

いずれにせよ、私のとりとめのない考えが何らかの考えを刺激するなら、聞いていただければ幸いです.

ありがとうございました

4

2 に答える 2

3

元の構造は完全に問題ありません。ステート マシンを構築していて、それを完全に合理的な方法で行っているため、これ以上慣用的にすることはできません。

必要に応じてできる唯一のことは、コードを少しモジュール化することです。

our %state = (last => 0, current => 0, next => 0);
our %extra_flags = ();
sub cond1($line) { return $next_state } # Returns 0 if cond==false
sub cond2($line) { return $next_state } # Returns 0 if cond==false

our %conditions = (
   0 => \&cond1
   1 => \&cond2  # flag1 is set
);

while (<INPUT>) {
   my $state = $state->{current};
   if ($state->{next} = $conditions{$state}->($_, $state)) {
      $do_stuff{$state}->{$next_state}->($line);
      $state->{last} = $state->{current};
      $state->{current} = $state->{next};
      next;
   }
}
于 2012-11-30T02:13:31.660 に答える
1

ファイルが実際に複数のループで処理されるのに適している場合、それは条件付きでエミュレートするよりもはるかに明確な方法です。

そうでない場合は、コードの周りにいくつかの例外があったとしても、説明した元のアプローチに固執することをお勧めします.

于 2012-11-30T02:10:38.300 に答える