2009/02/26(Thu)変数内での関数の展開

2009/02/26 23:43 Languages::Perl
変数の展開の展開 +αでは、埋め込んだ関数を展開して評価する方法を書いたが、あんな面倒な事をやらなくてもPerl本来の機能で簡単にできたらしい。

ダブルクオート(qq)内から関数を呼び出す

簡単な例を下に示す。
#!/usr/local/bin/perl

print qq|5*2は@{[a(5)]です}\n|;

sub a{
    return $_[0]*2;
}
答えは10と表示される。同様に、ヒアドキュメントでも有効だ。

ヒアドキュメントから関数を呼ぶ

#!/usr/local/bin/perl

print << "_EOM_";
5*2は@{[a(5)]}です。
_EOM_

sub a{
    return $_[0]*2;
}

いやぁ、今までPHPみたくヒアドキュメント風に書きつつ関数を展開することができないと思いこんでいたため、
  • ソースの上の方で関数の処理を束ね、それを一時変数に入れて、下の方のヒアドキュメントで大量に参照する
という方式か、
  • ヒアドキュメントではなく、q||やqq||を大量に使って文字列連結し、途中に関数呼び出しを挟む
という非効率極まりない書き方をしていた。あぁ、もったいな……。

@{[関数]}という構文は少々打ちづらいけど、とても便利なので、今後多用しようーっと!

ヒアドキュメントに匿名メソッドを埋め込む

欲を言えば、単発の関数だけじゃなくて匿名メソッド(無名メソッド)が呼べたら便利じゃん?*1
ということで、いろいろ試してみたらうまくいった。これすげー!
#!/usr/bin/perl

print << "_EOM_";
呼ばれたのは…
@{
    if(time%2){
        [&A];
    }else{
        [&B];
    }
}
_EOM_

sub A{
    return qq|A!|;
}

sub B{
    return qq|B!|;
}
結果はいわずもがな、
$ ./test.cgi
呼ばれたのは…
A!
$ ./test.cgi
呼ばれたのは…
B!
のようにtime%2の演算結果に従って変わります。
ちなみに、[&a];という部分をprint &a;などと書くと、ヒアドキュメントより先にそちらが実行されて
$ ./test.cgi
A!呼ばれたのは…
のようになるので、注意。


いやぁ、Perl万能だなぁ。

*1 : C#でdelegateによる匿名メソッドに毒されてまして……^^;