Text::ClearSilver - New ClearSilver binding in Perl

id:Craftworks さんから仕事をもらいまして、ClearSilverPerlバインディングを書きました。

ClearSilver はCで実装されたテンプレートエンジンで、高速だという話はあるものの、Yapc::Asia 2007で紹介されたほかはそれほど話題にも上らず、私も今回の話が来るまでは知りませんでした。

もっとも、Perlの世界で流行らないのは当然です。ClearSilverディストリビューションにはPerlモジュールが含まれているのですが、これの質が非常に低く*1Perlデータ→HDFデータ*2の変換も用意されていないため、Data::ClearSilver::HDFを使う必要がありました。また、メインのモジュールはCPAN経由でインストールすることもできませんでした。

しかし今や、上記の問題を解決したText::ClearSilverがあるので流行るといいですね!

ところで、今回初めてきちんと動くCライブラリのバインディングモジュールを書いたのでした。いくつか思ったことがあるのでメモしておきます。

  • ライブラリ本来のインターフェイスにこだわる必要はなく、むしろPerlの慣習に合わせたほうが使いやすい
    • Cライブラリは戻り値でエラーコードを返すことが多く、まず例外*3を放出しない。これを素直に移植すると非常に使いにくいので、適宜croak()したほうが使いやすいモジュールになる
  • Cライブラリを同梱する場合、Module::Installのno_index(@dirs)を使うとよい。ただし、再配布可能かどうかはライセンスを読んで確認すること
  • 元のライブラリについているLL言語バインディングは、必ずしもそのエキスパートが書いたとは限らないと知れ
  • Cのライブラリを書く際は、コールバックを登録するAPIをきちんと設計するとLL言語で拡張できてよい。ClearSlver はこの点が不十分で、ユーザー定義の関数を登録するAPIが使い物にならない。このため、T::CSでは本体にパッチを当てている
  • Cのライブラリを書く際は、malloc/freeをユーザーに見せない工夫が必要。ClearSilver はこの点がダメで、malloc した文字列を渡さなければならない場面がいくつかあるので恐ろしい

今回の仕事はとてもいい経験になりました。id:Craftworks さんありがとうございました!

*1:-wのもとで$cs->render()時に必ずuninitialized警告が出る、エラー処理が皆無、ドキュメントがWebにしかないなど。

*2:ClearSilverエンジンに与えるデータ形式

*3:longjump()やC++のexceptionなど