PHP 5.3のgoto

PHP 5.3のリリースマネージャ、Johannes Schlüterさんのブログの「A hidden gem in PHP 5.3」シリーズ第三弾、gotoについて。


Goto your Christmas presents with PHP 5.3 – Johannes Schlüter

ここ数日間、PHP 5.3の秘宝についていくつか紹介してきた。今はクリスマスだし、PHP次期バージョンの新しい言語機能について見てみることにしよう:

jump label演算子の追加 (制限されたgoto) (Dmitry, Sara)

過度な悪評をさけるため上記のNEWSエントリは意図的に不明確になっている。が、クリスマスに家族と共に過ごさずにこれを読んでいるってことは、君はギークでありPHP 5.3には名前空間の他にgotoも導入されるってことを知っていると思う。そう、これはgotoラベルだ。NEWSエントリで書かれているように、同じ実行単位(関数内または同じファイル中のグローバル部分)内にしかジャンプできず、またループ内へのジャンプもできないという制限がある。

gotoを知っているのならば、それが酷いものであるということも知っているだろう。ではなぜ我々はそれを追加したのか?gotoが許されるとても限られたケースがいくつかあるんだ。ひとつは生成されたコード。コードジェネレータはgotoを使うことでgoto無しの場合よりもよりよいコードを書くことができるし、どのみち誰も生成されたコードを見ようなんて思わない。二つ目のシチュエーションは長いコードの固まりがあるときで、しかもその中で実行を中断して色々な後始末をしなきゃならない場合。短い擬似コードだとこんな感じだ:

<?php
function process_file($filename) {
    $fp = fopen($filename, "r");
    if (!$fp) {
        goto cleanup;
    }
 
    $row = fread($fp, 1024);
    // 行に対して色々な処理をする
    if ($error_while_processing) {
        goto cleanup;
    }
 
    $a_few_bytes = fread($fp, 4);
    // また色々な処理 ...
        if ($error_while_processing) {
        goto cleanup;
    }
 
    /* ... */cleanup:
    fclose($fp);
}
?>

この他にも、コード全体をループで囲んでbreakを使うとか、try {} catchブロックで囲んで例外を投げるとか色々な方法はある。だが、gotoを使うとより綺麗になる(cleaner)。So have fun and use it with care!

Comments are closed.