1

次のスクリプトが機能しない理由を説明できる人はいますか? Label not found for "last SOME_BLOCK"エラーの原因は何ですか?

#!/usr/bin/perl
use v5.14;
SOME_BLOCK: {
    alarm 1;
    $SIG{ALRM} = sub {
        last SOME_BLOCK;
    };
    my $count = 0;
    while (1) {
        $count += 1;
        say $count;
    }
};
4

1 に答える 1

6

perldoclastにより、またはを介してサブルーチンを終了することnextは禁止されています(通常、警告がトリガーされます)。これは非常に厄介なためです。Perlは、スキップしようとしているブロックを見つけるためにスコープを動的に検索し、さまざまな関数からreturnを呼び出す必要があります(ただし、どの戻り値を使用する必要がありますか?)。一般的に安全です。return

シグナル処理のコンテキストでは、Perlはシグナルハンドラーを実行するためにスクリプトの実行を実際に一時停止する必要があるため、非常に面倒です。そのため、2つの別々の実行コンテキストが実行されており、シグナルハンドラコンテキストがメインコンテキストの制御フローに直接影響を与えることはできません。そのため、このエラーが発生します。

できることは2つあります。

  • (を使用して)例外をスローdieし、外側のブロックでキャッチします。これは、ほとんど何でも中断する可能性があるため、望ましくありません。
  • シグナルハンドラの外部で定義されたグローバルフラグを設定します(例:($caught_signal = 1))。都合の良い場所で内部コードでそれを確認します。
于 2013-02-23T13:45:35.020 に答える