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

Can someone help me change the loop below to not exit if 1, 2 or 3 is typed? I'd like it to ask the question "Please type in 1, 2 or 3 and click enter" for each time they input something not expected. So instead of typing in a "5" or an "a" and having the program stop, I'd like it to loop over and over again until they type in 1, 2 or a 3.
chomp (my $choice = <STDIN>); if ($choice == 1) { &hash1; } elsif ($choice == 2) { &hash2; } elsif ($choice == 3) { &hash3; } else { print "ERROR: Please type in either 1, 2 or 3."; print "\nYou must restart the program"; exit; }

Replies are listed 'Best First'.
Re: simple loop
by revdiablo (Prior) on Mar 24, 2004 at 04:24 UTC

    There are already a few other good replies, but none of the other monks have mentioned that fact that your code does not actually have a loop anywhere. It's easy to discern where you want the loop, but I think it should at least be pointed out that you don't have one.

    Here's a version using a while loop:

    while (1) { chomp(my $choice = <STDIN>); if ($choice == 1) { &hash1; } elsif ($choice == 2) { &hash2; } elsif ($choice == 3) { &hash3; } else { print "ERROR: Please type in either 1, 2 or 3.\n"; redo; } last; }

    Update: fixed code to actually do what was asked.

    You might want to add some checking to make sure $choice looks like a number before trying to use numeric comparisons against it. Scalar::Util's looks_like_number subroutine might be just the ticket.

Re: simple loop
by Zaxo (Archbishop) on Mar 24, 2004 at 03:47 UTC

    You can enclose the logic in curlies to form a bare block and replace the exit with redo.

    I'd prefer to organize the code refs as a real hash like so:

    { chomp (my $choice = <STDIN>); if (exists $codehash{$choice}) { &{$codehash{$choice}}; } else { print "ERROR: Please type in either 1, 2 or 3.\n"; redo; } }

    After Compline,
    Zaxo

Re: simple loop
by jweed (Chaplain) on Mar 24, 2004 at 03:37 UTC
    Smells a wee bit like homework, but try:
    LOOP: { $choice = <STDIN>; if ($choice == 1) { &hash1; } elsif ($choice == 2) { &hash2; } elsif ($choice == 3) { &hash3; } else { print "ERROR: Please type in either 1, 2 or 3.\n"; redo LOOP; } }



    Code is (almost) always untested.
    http://www.justicepoetic.net/
Re: simple loop
by spikey_wan (Scribe) on Mar 24, 2004 at 11:50 UTC
    What about this:
    use strict; use warnings; my $choice; while (1) { print "Please type in 1, 2 or 3 and press enter: "; chomp ($choice = <STDIN>); last if (($choice eq "1") or ($choice eq "2") or ($choice eq "3")); print "Sorry that was invalid.\n\n"; } print "\nThank you, you entered $choice.\n\nPress ENTER to exit\n"; <STDIN>;
Re: simple loop
by davido (Cardinal) on Mar 24, 2004 at 08:35 UTC
    Here's one way to do it:

    LOOP: { chomp ( my $choice = <STDIN> ); $choice == 1 && do { &hash1; last LOOP; }; $choice == 2 && do { &hash2; last LOOP; }; $choice == 3 && do { &hash3; last LOOP; }; print "ERROR: Please enter 1, 2, or 3.\n"; redo; }

    Dave