type holyshared = Engineer<mixed>

PHP、Hack、Ruby、OCaml、Rust、Javascript周りの技術ブログ

Hackで書いた自作のオプションパーサーをリファクタリングした

結構昔にHackでオプションパーサー書いていたのですが、しばらく面倒でメンテナンスを放置していました。 それをHHVM-3.21.0がリリースされてたタイミングで、メンテナンスしている他のパッケージと一緒にリファクタリングしました。

使いかたはこんな感じで、shortオプション、longオプション、オプションの説明、コールバック用のlambdaを指定していきます。 あとは使い方の設定を指定するして、parseメソッドに引数を指定するだけです。

<?hh //partial

use HHPack\Getopt as cli;
use HHPack\Getopt\App\{ ArgumentParser };

function main() : void {
    $help = false;
    $version = false;
    $fileName = 'test';

    $argParser = cli\app('example', '1.0.0')
        ->description("This cli application is example.\n\n")
        ->usage("  {app.name} [OPTIONS]\n\n")
        ->options([
            cli\on(['-h', '--help'], 'display help message', () ==> {
                $help = true;
            }),
            cli\on(['-v', '--version'], 'display version', () ==> {
                $version = true;
            }),
            cli\take_on(['-n', '--name'], 'file name', ($name) ==> {
                $fileName = $name;
            })
        ]);

    $args = $argParser->parse($argv);

    if ($help) {
        echo 'help on', PHP_EOL;
    }

    if ($version) {
        echo 'version on', PHP_EOL;
    }

    if ($fileName !== 'test') {
        echo 'name = ', $fileName, PHP_EOL;
    }
}
main();

CLIの場合、エントリポイントのソースはpartialモードを指定しないといけないので、(strictの場合はTOPレベルに実行可能なコードを書けない為)適当な関数にラップして、実行するのがいいと思います。

そうすると、型のチェックもやってくれるようになります。(ドキュメントに書いてある)

自分が真面目に書く場合は、strictモードに寄せたいので、アプリケーションのクラス書いて、runメソッドを実行みたいな薄い実装にすると思います。

https://github.com/hhpack/getopt/blob/master/example/app.hh

HHVM-3.21.0で色々チェックしてたけど、タイプチェッカーの性能が上がってて、古いバージョンでエラー出てなかった奴が出るようになったので、やっぱりバージョン上がるたびにチェックした方が良さそうです。