Pregunta

The question I have is a bit abstract, but I'll attempt to be clear in my statement. (This is something of a "rubber duck effect" post, so I'll be thankful if just typing it out gets me somewhere. Replies, however, would be brilliant!)

I have old fortran code that I can't change (at least not yet) so I'm stuck with its awkward output.

I'm using perl to post-process poorly annotated ascii output files, which, as you might imagine, are a very specialized mixture of text and numbers. "Ah, the perfect perl objective," you say. Yes, it is. But what I've come up with is pretty terrible coding, I've recently concluded.

My question is about the generic structure that folks prefer to use to achieve such an objective. As I've said, I'm not happy with the one I've chosen.

Here's some pseudocode of the structure that I've arrived at:

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

The objective of the above code is to be able to break the processing into blocks corresponding to the poorly partitioned ascii file -- there isn't much by way of "tags" in the file, so the conditions (cond1, cond2, etc.) are involved. The purpose of having the flags set is, among other reasons, to track the progress of the code through the file.

It occurs to me now that a better structure might be

while (<INPUT>) {
   do stuff;
}

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

In any event, if my rambling inspires any thoughts I'd appreciate hearing them.

Thank you

¿Fue útil?

Solución

Your original structure is perfectly fine. You're building a state machine, and doing it in a completely reasonable way that can't really be made any more idiomatic.

The only thing you can possibly do if you wish is to modularize the code a wee bit:

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

Otros consejos

If the file does indeed lend itself to being processed in multiple loops, that would be a much clearer way to do it than emulating that with conditionals, IMO.

If not, even if there are just a few exceptions to code around, it's probably better to stick with the original approach you describe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top