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

The following section calls a method and dependent on the return either uses last, performs the next command - or what I am after restarts the loop from the beginning. I need a "first" command. Is the best way to do this put another label control around COMMAND - break out of COMMAND to NEWCOMMAND and then reexecute COMMAND?
COMMAND: foreach my $CommandHsh (@{$command_section}){ $Result = $self->ExecuteCommand($CommandHsh); if ($Result eq "END"){ $self->{_logfile}->debug("Signal received to END command secti +on"); last COMMAND; } elsif ($Result eq "CONTINUE"){ $self->{_logfile}->debug("Signal received to CONTINUE command +section"); #next COMMAND; } elsif ($Result eq "RESTART"){ $self->{_logfile}->debug("Signal received to RESTART command s +ection"); redo COMMAND; } else { $self->{_logfile}->error("Incorrect exit type from ExecuteComm +and"); } } $self->{_logfile}->info("End of CommandSection"); }
This appears to work but is it the best way:-
RESTART: while ( 1 ) { COMMAND: foreach my $CommandHsh (@{$command_section}){ $Result = $self->ExecuteCommand($CommandHsh); if ($Result eq "END"){ $self->{_logfile}->debug("Signal received to END command sec +tion"); last COMMAND; } elsif ($Result eq "CONTINUE"){ $self->{_logfile}->debug("Signal received to CONTINUE comman +d section"); #next COMMAND; } elsif ($Result eq "RESTART"){ $self->{_logfile}->debug("Signal received to RESTART command + section"); next RESTART; } else { $self->{_logfile}->error("Incorrect exit type from ExecuteCo +mmand"); } } $self->{_logfile}->info("End of CommandSection"); last RESTART; }

Replies are listed 'Best First'.
Re: Loop Control - First?
by hmerrill (Friar) on Oct 28, 2003 at 14:35 UTC
    Just my preference, but I prefer to do things like that slightly differently - I don't like to "mix" the loops:
    RESTART: while ( 1 ) { COMMAND: foreach my $CommandHsh (@{$command_section}){ $Result = $self->ExecuteCommand($CommandHsh); $Restart = 0; # set to false if ($Result eq "END"){ $self->{_logfile}->debug("Signal received to END command secti +on"); last COMMAND; } elsif ($Result eq "CONTINUE"){ $self->{_logfile}->debug("Signal received to CONTINUE command +section"); #next COMMAND; } elsif ($Result eq "RESTART"){ $self->{_logfile}->debug("Signal received to RESTART command s +ection"); $Restart = 1; # set to true } else { $self->{_logfile}->error("Incorrect exit type from ExecuteComm +and"); } } ### end COMMAND foreach next RESTART if $Restart; ### only get here if NOT restarting - finish up ### $self->{_logfile}->info("End of CommandSection"); last RESTART; }
    HTH.
Re: Loop Control - First?
by simonm (Vicar) on Oct 28, 2003 at 15:35 UTC
    The outer block doesn't need to be a loop; a plain block is sufficient:
    ATTEMPT: { COMMAND: foreach my $CommandHsh (@{$command_section}){ $Result = $self->ExecuteCommand($CommandHsh); if ($Result eq "END"){ $self->{_logfile}->debug("Signal received to END command secti +on"); last COMMAND; } elsif ($Result eq "CONTINUE"){ $self->{_logfile}->debug("Signal received to CONTINUE command +section"); next COMMAND; } elsif ($Result eq "RESTART"){ $self->{_logfile}->debug("Signal received to RESTART command s +ection"); redo ATTEMPT; } else { $self->{_logfile}->error("Incorrect exit type from ExecuteComm +and"); } } $self->{_logfile}->info("End of CommandSection"); }
      The outer block doesn't even need to exist. If you use a goto, the solution will be more symmetric (yeah, getting more pleasing looking code by using goto!):
      COMMAND: foreach my $CommandHsh (@{$command_section}){ $Result = $self->ExecuteCommand($CommandHsh); if ($Result eq "END"){ $self->{_logfile}->debug("Signal received to END command secti +on"); last COMMAND; } elsif ($Result eq "CONTINUE"){ $self->{_logfile}->debug("Signal received to CONTINUE command +section"); next COMMAND; } elsif ($Result eq "RESTART"){ $self->{_logfile}->debug("Signal received to RESTART command s +ection"); goto COMMAND; } else { $self->{_logfile}->error("Incorrect exit type from ExecuteComm +and"); } } $self->{_logfile}->info("End of CommandSection");

      Abigail

Re: Loop Control - First?
by dragonchild (Archbishop) on Oct 28, 2003 at 15:01 UTC
    Personally, I'd use some form of signals. Not the $SIG{INT} stuff. More like try-catch signals.

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    ... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.