Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Am doing the following,
while (<STDIN>) { print "--> $_"; if ( /^2/ ) { break; } print "--> $_"; } while (<STDIN>) { print "==> $_"; }
Basically after getting the input which starts with 2, i want to handle the remaining lines in a different manner, so going to a different loop. But this break, is not breaking the first while loop ? I understand, it is my misunderstanding, but what is it, and how to solve it ?

Replies are listed 'Best First'.
Re: whats wrong with this break ?
by kennethk (Abbot) on Sep 17, 2010 at 13:37 UTC
    The issue is that break is not a keyword in Perl. You mean last. For a basic intro to how to control programmatic flow in Perl, see Loop Control in perlsyn.

    If you had used strict, Perl would have told you as much.

    use strict; use warnings; while (<STDIN>) { print "--> $_"; if ( /^2/ ) { break; } print "--> $_"; } while (<STDIN>) { print "==> $_"; }

    yields

    Bareword "break" not allowed while "strict subs" in use at fluff.pl li +ne 7. Execution of fluff.pl aborted due to compilation errors.

    Please read Use strict warnings and diagnostics or die (and The strictures, according to Seuss for a chuckle) to understand why strict will make your life dramatically easier.

      Ironically, you were right for years, decades, but as of 5.10 break IS a keyword in Perl. Just goes to show .... something.

      25$ perldoc -f break break Break out of a "given()" block. This keyword is enabled by the "switch" feature: see fe +ature for more information.

      As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Re: whats wrong with this break ?
by wfsp (Abbot) on Sep 17, 2010 at 13:34 UTC
    Try last (break out of a loop) instead of break (break out of a switch statement).

      excellent catch.... thanks.
        Have you considered using else instead of break?
        The break is going to make it harder to maintain, unless you heavily comment your code. Especially as this is not what you are actually doing with these lines but simplied to illistratrate your point, which will effective hide the break within your code.
        Using an else there instead will slow your script slightly for the additional check on every line, though the increase in maintainability might be well worth the cost.
Re: whats wrong with this break ?
by TomDLux (Vicar) on Sep 17, 2010 at 17:22 UTC

    Making the cpu break out of the loop at the point you want it to is the easy part. The harder part is making the code simple to understand 6 months from now, when you're in a hurry with a boss breathing down your neck, after a night of heavy drinking.

    The quick-and-easy-solution™ is to use labels so it's clear which component you're exiting, and why.

    HEADER: while (<STDIN>) { print "--> $_"; last HEADER if /^2/; print "--> $_"; }

    I'll also mention that I'm not fond of $_, except in the shortest of scripts. If you need to nest the loops, you have to use real variables. If you call routines, $_ may or may not be trampled. I find it simpler and easier to assign to variables from the start, and it improves clarity at the cost of a few characters. And notice that your desire to have the leading arrow forced you to have $_ in the print statement, rather than the supposedly economical print;.

    HEADER: while (my $line = <STDIN>) { print "--> $line"; last HEADER if '2' eq substr $line, 0, 1; print "--> $line"; }

    But if you refactor this chunk into a subroutine, it suddenly becomes a bit of documentation!

    process_file_header(); process_file_participants_list(); process_file_contract_details();

    Using subroutines rather than linear code ss especially useful if your document is not a linear flow but has components that can appear multiple times in random order. Of course, in the extreme case, you're writing an XML parser or re-inventing Expect. Challenges are good for the soul.

    given (determine_context()) { when ( $FOO ) { process_foo(); } when ( $BAR ) { its_a_bar(); } when ( $BAZ ) { woo_ha(); } default { confused(); } }

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.