Acme::StringFormat

Perl VMを拡張してStringFormat演算子を定義してみた。
http://search.cpan.org/dist/Acme::StringFormat/
RubyPythonなどで組み込みStringクラスにStringFormat演算子"%"が定義されているのがうらやましくてやった。実装はなんでもよかった*1今は反省している

use Acme::StringFormat;
say "[%s, %s!]" % "Hello" % "world";
# => [Hello, world!]
  • _enter()でPL_check[OP_MODULO]をsf_ck_modulo()に書き換える
  • sf_ck_module()では5.10.0から導入されたレキシカルヒントハッシュ*2のエントリを参照して,有効になっていればOPオブジェクトのop_ppaddrをsf_pp_modulo()に書き換える。ここまでがコンパイルタイムの話
  • sf_pp_modulo()がランタイムに%の処理を行う。これは左辺が文字列で右辺がオーバーロードされていないとき,最初に見つかったフォーマットパラメータを一つだけsprintf()で処理する
  • パラメータが複数あるときは%を重ねがけする。パラメータがないときに処理しようとすると警告発生

使い勝手は悪くないが,パフォーマンスが非常に悪い。ディストリビューションに入れてあるmisc/benchmark.plによると,sprintf()と比べ5倍ほど遅い。これはでは流石に遅すぎる。
いずれにせよタイプ数を減らす効果しかないので,Acme::として公開することにした。

*1:実際,overload.pmを使ってほぼ同じ機能を実装することもできる

*2:http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlpragma.pod