2016-05-18 11 views
4

このループは決して停止しない:これらの例でPerlで "最後の"動作が異なるのはなぜですか?

while (1) 
{ 
    while (1) 
    { 
     last; 
    } 
} 

をこのループはlastなければ

while (1) 
{ 
    do 
    { 
     last; 
    } 
    while (1); 
} 

を停止し、彼らは無限に似ています。 2番目のループ構造は、内部ループをループと見なさないようです。私は2番目の構造であると推定していますlastは実際には内側のループが始まる前に外側のループを終了します。しかし、なぜ? do{}が最初の実行を完了した後、内側ループが実際に「後で」開始しますか? perldoc -f lastから

+1

'はperldoc -f do':「ループ制御文' next'、 'last'、または' redo'ができないので、 'BLOCK'は、ループとしてカウントされませんありません。ブロックを終了または再起動するのに使用することができます。 " –

+1

@ikegami - 'perl -E 'と言う($ _)、最後は5 .. 10' –

+2

@ JimDavis面白いです。 'for'は' while'/'until'とは異なるセマンティクスを持ちます(' perl -e'last whileは '1 'は' 'ループブロックの外側で' 'Canできません'')。 'for'ステートメント修飾子にラベルを付けることができますが、' while'では 'perl -E'FOO:1.10'の最後のFOOとラベル付けすることはできません。 '1 while'、 'while(1){1}'、 '1 for 1'、' {1} 'のB :: Concise出力も比較してください。 '1 while 1'は' leaveloop'オペコードを生成します。 – ThisSuitIsBlackNot

答えて

3

最後に、このような評価 {}のような値を返すブロックを終了するために使用することができない、サブ{}、または実行{}、とgrepを終了するために使用すべきではありません()または map()操作。

do { 
    # ... 
} while (1); 

redoは、その中に適切に機能していない、ので、last、実際にはPerlでループではありませんnext

{ 
    do { 
     last; 
    } while (1); 
} 

は、より直感的な解決策を持っていることででしょう:あなたは、あなたが期待するようlastが機能することを可能にするためにブロック内の式を行うラップすることができますので

単一のブロックは、しかし実際にはループですexectutionを制御センチネル値:

my $should_stop = 0; 
do { 
    if (<some-condition>) { $should_stop = 1; } 
} while (!$should_stop) 
+0

うーん、これは重複しているとは思わなかった –