web-dev-qa-db-ja.com

PerlがIfステートメントから抜け出す

これはちょうど現れました:ifステートメントから抜け出すにはどうすればいいですか?私は長いif文を持っていますが、早い段階で脱出できる状況が1つあります。

ループでこれを行うことができます:

while (something ) {
    last if $some_condition;
    blah, blah, blah
    ...
}

ただし、ifステートメントでも同じことができますか?

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

ifステートメントをブロック内に配置でき、ブロックから抜け出すことができます。

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

または、サブルーチンを作成することができます(おそらくプログラム的にはより良いでしょう):

if ( some_condition ) {
    run_subroutine();
}

sub run_subroutine {
    blah, blah, blah
    return if $some_other_condition;
    blah, blah, blah
    ...
}

しかし、if条件を終了する方法はありますか?


解決

私が誰かのコードを手伝っていたので、質問が出ました。かなり長いifステートメントの中に、他のいくつかのifステートメントが埋め込まれていました。コードは次のようになりました。

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

これを行うことで、全体がより読みやすくなると思いました。

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

これは、ifステートメントの通常のフローが標準であることを示していますが、特定の条件下では、ifまたはlastループでnextまたはwhileを使用してループを終了するように、forステートメントが早期に終了しました。

mpapec's ラベルを使用することの解決策-ラベル自体を使用しない場合でも。ラベルは私のifの説明です:

IF-UNDER-CONDITION1:
{
    if ( $condition1 ) {
        last if $condition2;
        blah, blah, blah;
        last if $condition3;
        blah, blah, blah;
    }
}

これは標準のコーディング手法ではありませんが、コードの流れは十分に明らかであるため、典型的な低レベルのPerl開発者(私が去った後にこのコードを維持しなければならない開発者)はコードが何をしているかを把握し、維持することができます。彼らはその過程で何かを学ぶかもしれません。

26
David W.

basic block を使用できます。これは、lastnext、およびredoの影響を受けるため、それからブレークする可能性があります。

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";
  }
}
26
Сухой27
  • 空のfor()ループ内に配置し、ifの後にANDで区切るすべての場所に_last;_を追加します。少しいですが、動作します。トリックを説明するコメントを必ず追加してください。

    _for (;;) {
        if (condition) { 
            #code
            last if another_condition;
        }
        last;
    }
    _
  • goto を使用し、そのgotoのループの後にステートメントにラベルを付けます。永遠にのろわれます。

  • if内の追加ブロック(例:if () {{ code }})。初心者にとっては読みにくいかもしれませんが、コメントがあれば大丈夫です。

  • 独自のソリューション:ifをブロックします。読みやすさに関してはあまり明白ではありません。

  • 独自のソリューション:リターン付きサブルーチン。

    率直に言って、サブを呼び出すコストがパフォーマンス的に賢明でない限り、これは可読性に関する限り最もクリーンなソリューションです。

4
DVK

次のように、残りのifブロックを別のifステートメントの中に入れることができます。

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

「続行しますか?」に基づいてシーケンシャルifステートメントを使用する傾向があります。代わりに変数。きみの

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

に再配置することができます

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

DVKの答え に触発されて遊んでみたところ、少なくともPerl 5.26.1で動作するこのバリアントを思いつきました。

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

perlsyn ごとに、これは次と同等です:

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

continue ブロックでは、lastはメインループで実行された場合と同じ効果があります。したがって、ループはsome_conditionに応じて0回または1回実行されます。

テスト

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

さまざまなXおよびY値に対して、次の結果があります。

X Y   Prints
-----------------------
0 0   (nothing)
0 1   (nothing)
1 0   hello, goodbye
1 1   hello
0
cxw

別の方法は、匿名サブルーチンを使用することです。
注:この方法はお勧めしません追加されたスコープの複雑さ(下記の注を参照)。それは可能な答えの完全性のためだけです。

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

注:ルーチン内で宣言された変数は、ourの代わりにmyを使用する必要があります。コードの残り

0
vol7ron

whileループを保持して、lastを使用できるようにしますが、ループが1回だけ実行されるようにします

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
    ...
}
0