2日目 - コマンドラインとMAIN関数の交流

この記事は"Perl6 Advent Calendar"エスパー和訳したものです。大意は合っていると思われるものの、内容は保証しません。


<原文>


二日目 - コマンドラインとMAIN関数の交流 (原文/Moritz)

Day 2 – Interacting with the command line with MAIN subs
By Moritz

Unix環境では、多くのスクリプトコマンドラインから引数やオプションを受け取ります。Perl6では、とても簡単にこれらを受け取ることができます。

In Unix environment, many scripts take arguments and options from the command line. With Perl 6 it’s very easy to accept those:

    $ cat add.pl
    sub MAIN($x, $y) {
        say $x + $y
    }
    $ perl6 add.pl 3 4
    7
    $ perl6 add.pl too many arguments
    Usage:
    add.pl x y

ただMAINという名前の関数とシグネチャを書くだけで、自動的にコマンドラインパーサとコマンドライン引数のシグネチャの仮引数($xと$y)への束縛、さらに(呼び出された時にコマンドライン引数とシグネチャが合致しなかったなら)Usage Messageを得ることができます。

By just writing a subroutine called MAIN with a signature, you automatically get a command line parser, binding from the command line arguments into the signature variables $x and $y, and a usage message if the command line arguments don’t fit.

Usage MessageはUSAGE関数を別に定義することでカスタマイズができます。

The usage message is customizable by adding another sub called USAGE:

    $ cat add2.pl
    sub MAIN($x, $y) {
        say $x + $y
    }
    sub USAGE() {
        say "Usage: add.pl <num1> <num2>";
    }
    $ perl6 add2.pl too many arguments
    Usage: add.pl <num1> <num2>

MAIN関数をmulitとして定義することで、使い分けられる構文をいくつか定義できます。つまり定数を用いたディスパッチです:

Declaring the MAIN sub as multi allows declaring several alternative syntaxes, or dispatch based on some constant:

    $ cat calc
    #!/usr/bin/env perl6
    multi MAIN('add', $x, $y)  { say $x + $y }
    multi MAIN('div', $x, $y)  { say $x / $y }
    multi MAIN('mult', $x, $y) { say $x * $y }
    $ ./calc add 3 5
    8
    $ ./calc mult 3 5
    15
    $ ./calc
    Usage:
    ./calc add x y
    or
    ./calc div x y
    or
    ./calc mult x y

名前付きパラメータはオプションに相当します:

Named parameters correspond to options:

    $ cat copy.pl
    sub MAIN($source, $target, Bool :$verbose) {
        say "Copying '$source' to '$target'" if $verbose;
        run "cp $source $target";
    }
    $ perl6 copy.pl calc calc2
    $ perl6 copy.pl  --verbose calc calc2
    Copying 'calc' to 'calc2'

パラメータをBool型として宣言した場合は値を受け取りません。逆に言えばBool型の型制約が無ければ引数を取ります:

Declaring the parameter as Bool makes it accept no value; without a type constraint of Bool it will take an argument:

    $ cat do-nothing.pl
    sub MAIN(:$how = 'fast') {
        say "Do nothing, but do it $how";
    }
    $ perl6 do-nothing.pl
    Do nothing, but do it fast
    $ perl6 do-nothing.pl --how=well
    Do nothing, but do it well
    $ perl6 do-nothing.pl what?
    Usage:
    do-nothing.pl [--how=value-of-how]

要約すると、Perl6はサブルーチンのシグネチャとmultiを使うだけで、組み込みのコマンドラインパーサとUsage messageを提供してくれるということです。

In summary, Perl 6 offers you built-in command line parsing and usage messages, just by using subroutine signatures and multi subs.

上手く書けば、宣言文は今までになく簡単なものになるでしょう。

Writing good, declarative code has never been so easy before.