Comment sortir d'une boucle en Perl?

295

J'essaie d'utiliser une breakinstruction dans une forboucle, mais comme j'utilise également des sous-marins stricts dans mon code Perl, je reçois une erreur disant:

Les mots nus "break" ne sont pas autorisés lorsque "strict subs" est utilisé à la ligne 154 de ./final.pl.

Existe-t-il une solution de contournement pour cela (outre la désactivation des sous-marins stricts)?

Mon code est formaté comme suit:

for my $entry (@array){
    if ($string eq "text"){
         break;
    }
}
Zain Rizvi
la source
22
Et si vous n'aviez pas de "sous-marins stricts", vous auriez obtenu une erreur d'exécution à la place quand il n'aurait pas pu trouver un sous-nom nommé "break".
Paul Tomblin

Réponses:

441

Oh, je l'ai trouvé. Vous utilisez le dernier au lieu de la pause

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}
Zain Rizvi
la source
Bien que ce soit simplement une différence sémantique et ne représente pas autre chose que la cohérence textuelle avec la commande "next".
Razor Storm
1
sans oublier que «pause» est un mot-clé expérimental dans> 5.010 non? de sorte que vous pourriez obtenir une erreur de blocage donnée à l'extérieur, non pas que vous devriez l'utiliser. La seule façon de fonctionner serait que vous utilisiez une boucle while à l'intérieur d'un bloc donné, puis que vous coupiez, ce qui en théorie fonctionnerait comme vous le vouliez si (et seulement si) le bloc donné ne contenait que la boucle while, et en supposant que vous vous nourrissiez juste étant donné une variable scalaire ... mais pourquoi tout cela fonctionne juste pour utiliser une pause, c'est (très) une mauvaise forme, sans parler de (bla!) dire simplement, son "possible" n'est tout simplement pas bon idée et pas ce que vous pensez que c'est
osirisgothra
25
pour une raison quelconque, je ne peux pas me souvenir de ce mot-clé «dernier». finissent toujours par googler la `` boucle de rupture perl '' :(
Thupten
Fonctionne de même pour les whileboucles (). my @array = ("_", "apple", "orange"); my $thing; while ($thing = shift @array){ last if $thing =~ /[A-Za-z]/; } print($thing); # "apple"
HoldOffHunger
175

Données supplémentaires (au cas où vous auriez plus de questions):

FOO: {
       for my $i ( @listone ){
          for my $j ( @listtwo ){
                 if ( cond( $i,$j ) ){

                    last FOO;  # --->
                                   # |
                 }                 # |
          }                        # |
       }                           # |
 } # <-------------------------------
Kent Fredric
la source
2
Vous n'avez pas vraiment besoin des accolades après FOO:
cjm
14
Vous le faites si vous avez un autre code juste après la boucle for my $ i que vous souhaitez également ignorer. L'extérieur {} est un bloc nu, qui est lui-même une sorte de boucle amusante qui peut être last / redo / next'd.
ysth
18

Fonctionnerait simplement lastici:

for my $entry (@array){
    if ($string eq "text"){
         last;
    }
}

Si vous avez des boucles imbriquées, vous quitterez la boucle lastla plus interne. Utilisez des étiquettes dans ce cas:

LBL_SCORE: {
    for my $entry1 (@array1) {
        for my $entry2 (@array2) {
            if ($entry1 eq $entry2) { # Or any condition
                last LBL_SCORE;
            }
        }
    }
 }

Étant donné une lastinstruction, le compilateur sortira des deux boucles. La même chose peut être faite dans n'importe quel nombre de boucles, et les étiquettes peuvent être fixées n'importe où.

Kamal Nayan
la source
6

Sur une grande itération, j'aime utiliser des interruptions. Appuyez simplement sur Ctrl+ Cpour quitter:

my $exitflag = 0;
$SIG{INT} = sub { $exitflag=1 };

while(!$exitflag) {
    # Do your stuff
}
MortenB
la source
Suggestion très utile en effet. +1
Keve
@PeterMortensen - cela fonctionne très bien dans les fenêtres, la seule chose à garder à l'esprit pour les fenêtres peut être d'activer le rinçage automatique si vous imprimez sur STDOUT '$ | = 1; `
MortenB