ドメイン限定でコードジェネレーション

こんにちは、らいあです。
Dinoのプログラマーは毎日いろんなツールや関数を作って遊んでいます。

みなさんもライブラリってよく作りますよね?今日は、そのライブラリ製作の一手法として、コードジェネレータについて書いてみようと思います。

※コードジェネレータとは※

その名のとおり、ソースコードを生成するツールのことです。設定ファイルやDSL言語を書いてツールにかけると、ターゲットのアーキテクチャに対応したソースコードができあがる。自分でソースを書く必要がないのでバグも出にくいし、設定ファイルをなるべく共通化すれば自動的にDRYにもなる。

たとえばRoRには大量のコードジェネレータが付属していますよね。PHPであれば、ORマッパや管理画面生成ソフトなどそこそこ存在するようです。

設定次第でいかようにも汎用的に使えるのがコードジェネレータの特徴と言えるかと思います。とても便利な考え方です。

※ドメインを限定してコードジェネレーション※

汎用的で堅牢なコードジェネレータは、その作成のために非常に高度なスキルを必要とします。いわゆる『達人プログラマ』と言われる人々の仕事領域になろうかと思います。

今日紹介したいのは、そういった「汎用的なコードジェネレータ」ではなく、ドメイン限定のコード生成についてです。「その案件専用の書き捨てコードジェネレータ」といえば伝わりやすいでしょうか。

よって必然的に、よりカジュアルな内容になります。DSLToolsやHibernateToolsといった重厚なツールとは、規模も問題領域もそもそも別物だと考えてください。

※例※

実際の仕事で作ったものです。
以前アシアルのゆどうふさんが絵文字表をJSON化して公開してくれました。これを案件で使おうと思いまして、ためしにプログラムに組み込んでみたのです。

すると、サイズが巨大なうえにJSONの変換も重いものですから、私の低スペックなノートパソコンでは、読み込むだけで0.5秒くらいかかるわけです。これではちょっとそのまま案件に組み込むのはいやだなあと思いました。

この案件の前提は以下のようなものでした。
1. HTML上に『EMOJI:120』等と書くと適切なキャリア用絵文字に変換される。
2. テンプレートはUTF8で書いて、入出力はSJISで行う。
3. 絵文字出力はSJISのバイナリで素直に吐く。
4. SJISの絵文字入力をEMOJI番号に変換してDBに保存する。

では、ということで、以下のようなコードジェネレータを作りました。
まず表(※1)のようなEMOJI番号→3キャリア用絵文字コードの変換表をつくって、その表をコードジェネレータにかけて、ソース(※2)のようなPHPのファイルを生成しました。この際にゆどうふさんのJSONが活躍したわけです(Thanks to ゆどうふさん)。

(1)
1	F89F	E04A	44	晴れ
2	F8A0	E049	107	曇り
3	F8A1	E04B	954	F8A2	E048	1915	F8A3	E13D	16	雷
:
:

↓コード生成

(※2)
<?php // auto generated by emoji_generate.php
function emojiDoCoMo_common2utf()
{
    static $i = array(
        1 => "\xEE\x98\xBE", // 晴れ
        2 => "\xEE\x98\xBF", // 曇り
        3 => "\xEE\x99\x80", // 雨
        :
        :

これによって、入力x出力x3キャリア、で計6つの関数が生成できました。関数のロードはこれでずっと軽量になりましたので、安心して案件に投入することができました。EMOJI番号は案件がはじまれば変動するわけもないですし、SJIS<=>UTF8バイナリ以外の変換はどうせ行わないので取り込む必要もなかったわけです。

※静的生成が動的生成に勝る点※

(1)わかりやすい
やはりソースコードがリポジトリに存在して、目で追えるというのは安心感があります。僕のようなスキルの低い層にとってこれは非常に重大な利点なのです。またエディタのコード補完が利くのも嬉しい副作用だと思います。

(2)高速軽量
もともとコードジェネレーションは静的なリンクが導かれて、相対的には軽量です。とくに今回のように案件専用に作りこんでしまうことで、さらに有利に運ぶことができます。

※おわりに※

いかがでしたでしょうか。このような使い捨てコード生成ツールを僕はよく作って案件に使っています。たとえばDBの生の値を日本語ラベルに変換する(View→Modelの)関数、とかいったようなものです。

みなさんはこんなのじゃなくて、超高性能な汎用コードジェネレーターをどんどん作って、ぜひオープンソースで公開してくださいね!

コメント / トラックバックはありません

コメントする