perl6のコード例

昨年クリスマスにリリースされたと噂されているperl6はスコープを抜けた時に実行するコードをLEAVEでかける。例えばfile処理は

given "file.txt".IO.open(:w) -> $fh {
  LEAVE $fh.close;
  $fh.say("hello world!");
};

と書くとよい。また

{
  my %old = %*ENV;
  LEAVE { %*ENV = %old }
  do-something-with-ENV();
}

と書けばdo-something-with-ENVで何をやろうとスコープを抜けたあとは環境変数がもとに戻る。 ただ、この場合はperl5で言うところのlocalと同じ働きをするtempを使って

{
  temp %*ENV;
  do-something-with-ENV();
}

と書いた方がすっきりする。

さて、perl6 module mi6には

sub withp6lib(&code) {
  temp %*ENV;
  %*ENV<PERL6LIB> = "lib/";
  &code();
}

sub test() {
  withp6lib {
    run <prove -e perl6 t/>;
  };
}

というコードがある。これはtest()の時だけ環境変数PERL6LIBを設定するコードである。 これはこれでいいのだが、traitを使うとさらにカッコよくかけることに気づいた。

multi trait_mod:<is>(Routine $code, :$with-perl6lib) {
  $code.wrap: {
    temp %*ENV;
    %*ENV<PERL6LIB> = "lib/";
    callsame();
  };
}

sub test() is with-perl6lib {
  run <prove -e perl6 t/>;
}  

multi trait_modのところがtraitの定義であり、その内部では$codeをwrapし、環境変数PERL6LIBを設定している。 callsame()は$codeを実行するという意味である。

perl6は書けば書くほど新しい文法が発見される楽しい言語で書き味が素晴らしい。 実際のところ上記も、もっといい書き方があるのかもしれない。

もしperl6を実際書いてみたいという方がいるなら、perl6/roast, perl6/specs あたりをgit cloneして全文をgrep検索することをお勧めしたい。