Perl代码结构用于后处理

3
我有一个比较抽象的问题,但我会尽力清晰地陈述。这是一篇“橡皮鸭效应”文章,所以如果将其打出来对我有所帮助,我将不胜感激。然而,如果有回复,那就太棒了!
我有一些老的Fortran代码,目前我不能改变它(至少暂时不能),所以我只好使用其糟糕的输出结果。我使用Perl对其进行后处理,这些文件往往是文本和数字的混合体,非常专业化。你可能会说:“啊,这正是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;
}

无论如何,如果我的话激发了您的任何想法,我将不胜感激地听取它们。
谢谢。

1
你需要提供一个输入格式的样本以及你期望的输出。 - jordanm
1
感谢您的评论,jordanm。理想情况下,那应该是正确的方法,我明白这一点。但由于我不想让问题负担过重,所以选择了伪代码方法。我经常需要做这样的事情,因此我认为抽象方法可能会产生更普遍适用的东西。同时,感谢@DVK的采纳答案,我没有失望。那正是我在寻找的东西。 - user1357713
2个回答

2

您的原始结构非常好。您正在构建一个状态机,并以完全合理的方式进行构建,无法更加惯用。

如果您希望的话,唯一可能要做的就是稍微模块化代码:

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;
   }
}

1
谢谢。这正是我在寻找的东西。已投票并接受。 - user1357713

0
如果文件确实适合在多个循环中处理,那么用条件语句模拟的方式相比之下就不如使用多个循环来得清晰易懂,这是我的看法。
如果不适合多个循环处理,即使只有几个需要特殊处理的情况,最好还是坚持原来的方法。

是的,我打算尝试两种方法,采用 @DVK 建议的模块化。 - user1357713

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接