could someone please explain if the infinite "while (1)" loop is required for this?

To really see why an infinite while() loop was used, let's try re-writing the code to remove or replace that loop.

In all of the code below, we will assume that the user already knows to just press ENTER to exit.

Here is the original code, shrunk to the minimum needed to illustrate the issue:

while (1) { print 'Please enter a word: '; chomp(my $word = <STDIN>); last if $word =~ /^\s*$/; print "You entered '$word'\n"; }
If we did not need to prompt for input, and STDIN was magically auto-chomping, we could use a while(my $word=<STDIN>){...} construct. Since neither of those is true, what *can* we put in the while() condition to make it finite?

Let's try checking for the empty $word in the while() condition:

# Had to duplicate the prompt, <read>, and chomp. # Duplication is bad! # Use the DRY principle: [D]on't [R]epeat [Y]ourself! my $word; print 'Please enter a word: '; chomp($word = <STDIN>); while ( $word !~ /^\s*$/ ) { print "You entered '$word'\n"; print 'Please enter a word: '; chomp($word = <STDIN>); }

Let's try that again, but not do any work outside the loop:

# Had to add `not defined $word` to handle the special case # during the first time through the loop. Very Ugly! # Had to duplicate code `$word !~ /^\s*$/` to prevent the # final ENTER from printing "You entered ''" as it exits # the loop. my $word; while ( ( not defined $word ) or ( $word !~ /^\s*$/ ) ) { print 'Please enter a word: '; chomp($word = <STDIN>); if ( $word !~ /^\s*$/ ) { print "You entered '$word'\n"; } }

Maybe initializing $word will help:

# Instead of using `not defined $word`, I force # non-whitespace into $word. # Still very ugly. # Still had to duplicate code `$word !~ /^\s*$/` my $word = 'JunkToPreventFailingTheFirstLoop'; while ( $word !~ /^\s*$/ ) { print 'Please enter a word: '; chomp($word = <STDIN>); if ( $word !~ /^\s*$/ ) { print "You entered '$word'\n"; } }

Invert the while() loop into a do...while loop?

# Still had to duplicate code `$word !~ /^\s*$/` my $word; do { print 'Please enter a word: '; chomp( $word = <STDIN> ); if ( $word !~ /^\s*$/ ) { print "You entered '$word'\n"; } } while $word !~ /^\s*$/;

We *can* use a finite while() loop by moving the prompt/<read>/chomp into a sub-routine.

sub prompt { my ($prompt_string) = @_; print $prompt_string; my $input = <STDIN>; chomp $input; return $input; } # Success! while ( my $word = prompt('Please enter a word: ') ) { print "You entered '$word'\n"; }

Since that prompt() sub would be useful in many different programs, it should be turned into a module.
TheDamian already did, and his IO::Prompt module is on CPAN.

use IO::Prompt; while (my $word=prompt 'Please enter a word: ', -while => qr/\S/) { print "You entered '$word'\n"; }

I would conclude that the Llama's use of the infinite while() loop is the clearest option that does not involve a prompt() sub or module.


In reply to Re: Don't re-read file for each new pattern... by Util
in thread Don't re-read file for each new pattern... by cgmd

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.