3

我的问题有点抽象,但我会尽量在我的陈述中说清楚。(这是一个“橡皮鸭效应”的帖子,所以如果只是把它输入到某个地方,我会很感激的。但是,回复会很棒!)

我有旧的 fortran 代码,我无法更改(至少现在还没有),所以我被它笨拙的输出所困扰。

我正在使用 perl 对注释不佳的 ascii 输出文件进行后处理,正如您可能想象的那样,它是文本和数字的非常专业的混合体。“啊,完美的 perl 目标,”你说。是的。但是我最近得出的结论是,我想出的是非常糟糕的编码。

我的问题是关于人们更喜欢用来实现这样一个目标的通用结构。正如我所说,我对我选择的那个不满意。

这是我得到的结构的一些伪代码:

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

如果该文件确实适合在多个循环中进行处理,那么这将是一种比使用条件 IMO 模拟更清晰的方法。

如果没有,即使只有一些例外情况可以编写代码,最好还是坚持使用您描述的原始方法。

于 2012-11-30T02:10:38.300 回答