in reply to A way to avoid repeated conditional loops

... while ( <FILE> ) { if ( /alpha/ ) { some code #1 last; } else { some code #2 } } while ( <FILE> ) { some code #2 } ....

Replies are listed 'Best First'.
Re^2: A way to avoid repeated conditional loops
by JavaFan (Canon) on Aug 24, 2011 at 10:57 UTC
    I wonder whether the copying of some code #2 is worth the avoidance of the test. Another way of writing it, with the same duplication:
    while (<FILE>) { if (/alpha/) { some code #1; while (<FILE>) { some code #2; } } else { some code #2; } }
Re^2: A way to avoid repeated conditional loops
by ikegami (Patriarch) on Aug 24, 2011 at 17:55 UTC

    You can't rely on readline returning EOF or errors more than once. Fix:

    OUTER: { for (;;) { defined( my $_ = <$fh> ) or last OUTER; if (/alpha/) { f(); last; } else { g(); } } while (<$fh>) { g(); } }

    Update: The remainder of this post is wrong.

    You can get rid of the duplicate g() by making the loops bottom tested.

    OUTER: { defined( my $_ = <$fh> ) or last OUTER; for (;;) { if (/alpha/) { f(); last; } defined( $_ = <$fh> ) or last OUTER; } for (;;) { g(); defined( $_ = <$fh> ) or last OUTER; } }

    You can squish it down a bit:

    LOOP: { defined( my $_ = <$fh> ) or last; if (/alpha/) { f(); redo; } for (;;) { g(); defined( $_ = <$fh> ) or last; } }

    Look at that, g() is not even duplicated anymore!!

      Why is your for loop idiom better than AR's or JavaFan's while loop statements above?

        I already pointed out that AR's version is wrong. You can't rely on readline returning EOF or errors more than once.

        I thought mine was better than JavaFan's because it lead to the elimination of the duplicate "g()", but that turned out to be a mistake (as per my earlier update).

        I still prefer mine over JavaFan's, though. Since mine flows from top to bottom, it requires less skipping around to follow the code.

      The squished version is really cool :) It looks I got my solution!

      Many thanks ikegami!

        That version doesn't do anything until it reaches the first alpha. Is that really what you want?
Re^2: A way to avoid repeated conditional loops
by runrig (Abbot) on Aug 24, 2011 at 17:00 UTC
    If 'some code #2' is very small or can be packaged into a single function call, I might go with that. Or I might just make it obvious that we only want/expect this once in the one loop:
    my $got_alpha; while (<FILE>) { unless ($got_alpha) { if (/alpha/) { #...alpha code $got_alpha++; next; } } # ...more code }
    Update: And I just noticed the part in the OP where it says "without a flag variable"...oh, well...

      I think you missed the point of the original post. Deus Ex wants to get rid of running the conditional as soon as "alpha" is seen. Your code substitutes that for another conditional (that doesn't use the regex engine, but still).

Re^2: A way to avoid repeated conditional loops
by Deus Ex (Scribe) on Aug 24, 2011 at 10:43 UTC

    Interesting. I would never think of doing like this. Thanks :)

    The only point, at first glance, would be that you get twice the "while" loop. I'm trying to understand if you can avoid such "ugly" (take the word for it) structures. Thanks though.

Re^2: A way to avoid repeated conditional loops
by ikegami (Patriarch) on Aug 24, 2011 at 17:43 UTC

    You can't rely on readline returning EOF or errors more than once.