Perl Breaking out of an If statement

梦想与她 提交于 2019-12-03 01:12:56

You can use basic block which is subject to last, next and redo, so there is possible break from it.

if ($condition) {EXIT_IF:{

   last EXIT_IF; # break from code block

   print "never get's executed\n";
}}

EXIT_IF: {
  if ($condition) {

     last EXIT_IF; # break from code block

     print "never get's executed\n";
  }
}
  • Put it inside an empty for() loop, and add last; everywhere you want to break out AND after the if. A bit ugly but works. Make sure to add comments to explain the trick.

    for (;;) {
        if (condition) { 
            #code
            last if another_condition;
        }
        last;
    }
    
  • use goto and label a statement after your loop for that goto. Be forever damned.

  • Extra block inside the if (e.g. if () {{ code }}). May be hard to read for novices but OK if accompanied by a comment.

  • your own solution: block around if. Not very obvious readability-wise.

  • your own solution: subroutine with return.

    Frankly, unless the cost of calling a sub matters performane wise, this is the cleanest solution as far as readability.

You could put the rest of your if block inside another if statement, like this:

if (some_condition) {
    blah, blah, blah
    if (!$some_other_condition) {
        blah, blah, blah
        ...
    }
}

Another alternative is to use an anonymous subroutine.
Note: I don't recommend this method because of the added scoping complexity (see note below); it is just for completeness of possible answers.

if( $true_condition ){
   (sub{
       return if $true_condition;
       ...
   })->();
}

Note: any variables declared w/in the routine must use our instead of my if you wish to use them in the rest of the code.

I tend to use sequential if-statements based on a "do I continue?" variable instead. Your

if ( $condition1 ) {
  blah, blah, blah;
  if ( not $condition2 ) {
     blah, blah, blah;
     if ( not $condition3 ) {
        blah, blah, blah;
     }
  }
}

can be rearranged to

my $ok = $condition1;
if ($ok) {
  blah, blah, blah;
  $ok = not $condition2;
}
if ($ok) {
  blah, blah, blah;
  $ok = not $condition3;
}
if ($ok) {
  blah, blah, blah;
}

Keep your while loop so you can use last but also make sure that the loop is executed at most once

my $loop_once = 1;
while ( $loop_once-- and some_condition ) {
    blah, blah, blah
    last if $some_other_condition; # No need to continue...
    blah, blah, blah
    ...
}

I was inspired by DVK's answer to play around, and I came up with this variant that works at least on Perl 5.26.1:

for( ; some_condition ; last ) {
    blah, blah, blah
    last if $some_other_condition; # No need to continue...
    blah, blah, blah    
}

Per perlsyn, this is equivalent to:

while (some_condition) {
    blah, blah, blah
    last if $some_other_condition; # No need to continue...
    blah, blah, blah    
} continue {
    last;
}

In a continue block, last has the same effect as if it had been executed in the main loop. Therefore, the loop will execute zero or one times, depending on some_condition.

Tests

perl -E 'my ($cond, $other)=(X, Y); 
         for(;$cond;last) { say "hello"; last if $other; say "goodbye" }'

has the following results, for various X and Y values:

X Y   Prints
-----------------------
0 0   (nothing)
0 1   (nothing)
1 0   hello, goodbye
1 1   hello
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!