Akki Javed
Akki Javed

Reputation: 215

Re-run a loop iteration

I have this program which takes a array of words and asks user to type a sentence which has each of the word from the array:

@words = qw(Hi world thanks);
foreach $word (@words) 
{
        print "Enter a line with word:$word\n";
        chomp($input = <STDIN>);
        if($input=~/$word/i) 
        {
                print "Great\n";
        } else {
                print "Incorrect. Type a line containing $word\n";
        }
}

If the user types a input with the word, it works fine. But if he doesn't It only prints the error message and moves to the next word. I want it it prompt the user to re-enter inputs for the same word. But how ? I tried next it did not work.

Upvotes: 7

Views: 2374

Answers (3)

TLP
TLP

Reputation: 67900

While redo is definitely cuter, here's a version with while ... continue. It relies on an inner loop that is exited only when the right word is entered, and prints a correction for each wrong answer.

use strict;
use warnings;

my @words = qw(Hi world thanks);
foreach my $word (@words) {
    print "Enter a line with word: $word\n";
    while (my $input = <>) {
        last if $input =~ /$word/;
    } continue {
        print "Incorrect. Type a line contaning $word\n";
    }
    print "Great\n";
}

Note that chomp is not required in this case.

Upvotes: 4

Joel Berger
Joel Berger

Reputation: 20280

I would create an infinite while loop to exit out of:

#!/usr/bin/env perl

use strict;
use warnings;

my @words = qw(Hi world thanks);
foreach my $word (@words) {
  print "Enter a line with word: $word\n";
  while (1) {
    chomp( my $input = <STDIN> );
    if( $input=~/$word/i )  {
      print "Great\n";
      last;
    } else {
      print "Incorrect. Type a line contaning $word\n";
    }
  }
}

of course I would probably separate the logic of each individual word into a sub, then loop over that:

#!/usr/bin/env perl

use strict;
use warnings;

my @words = qw(Hi world thanks);
get_word($_) for @words;

sub get_word {
  my $word = shift or die "Need a word";
  print "Enter a line with word: $word\n";
  while (1) {
    chomp( my $input = <STDIN> );
    if( $input=~/$word/i )  {
      print "Great\n";
      last;
    } else {
      print "Incorrect. Type a line contaning $word\n";
    }
  }
}

Upvotes: 3

codaddict
codaddict

Reputation: 454980

You can use a redo in this case to restart the current iteration.

foreach my $word (@words) 
{
        print "Enter a line with word:$word\n";
        chomp($input = <STDIN>);
        if($input=~/$word/i) 
        {
                print "Great\n";
        } else {
                print "Incorrect. Type a line contaning $word\n";
                redo; # restart current iteration.
        }
}

A less-recommended alternative is to use a goto:

foreach my $word (@words)
{
        INPUT:print "Enter a line with word:$word\n";
        chomp($input = <STDIN>);
        if($input=~/$word/i)
        {
                print "Great\n";
        } else {
                print "Incorrect. Type a line contaning $word\n";
                goto INPUT;
        }
}

Upvotes: 20

Related Questions