Erlangのファイルのテンプレートの利用と独自テンプレートの作成

Erlang Advent Calendarの4日目が空いていたので、あまり中身はないですが、Erlangで使えるファイルのテンプレートの利用方法と、ユーザ独自のテンプレートの作成方法について書く。

# テンプレートの使い方

## テンプレートの一覧を表示

テンプレートの一覧は **./rebar list-templates** を打てば見ることができる。

##### 動作例

```shell-session
$ ./rebar list-templates
=> ${APPNAME} (list-templates)
  * stdzero: /home/${USERNAME}/.rebar/templates/stdzero.template (file) (variables: "yearno, appid")
  * stdapp: /home/${USERNAME}/.rebar/templates/stdapp.template (file) (variables: "author, yearno, desc, appid")
  * stdsrv: /home/${USERNAME}/.rebar/templates/stdsrv.template (file) (variables: "author, yearno, srvid")
  * stdmod: /home/${USERNAME}/.rebar/templates/stdmod.template (file) (variables: "author, yearno, modid")
  * simplesrv: priv/templates/simplesrv.template (escript) (variables: "srvid")
  * simplenode: priv/templates/simplenode.template (escript) (variables: "nodeid")
  * simplemod: priv/templates/simplemod.template (escript) (variables: "modid")
  * simplelib: priv/templates/simplelib.template (escript) (variables: "libid")
  * simplefsm: priv/templates/simplefsm.template (escript) (variables: "fsmid")
  * simpleevent: priv/templates/simpleevent.template (escript) (variables: "eventid")
  * simpleapp: priv/templates/simpleapp.template (escript) (variables: "appid")
  * ctsuite: priv/templates/ctsuite.template (escript) (variables: "testmod")
  * basicnif: priv/templates/basicnif.template (escript) (variables: "module")
$
```

カレントディレクトリにrebar([GitHub](https://github.com/rebar/rebar))がなければどこかから持ってくるかパスを通す。

`simplesrv` から `basicnif` までが標準で存在するテンプレートである。
`stdzero` から `stdmod` までは後から説明する独自テンプレートだ。

### 各テンプレートについて

名前を見たらわかるが、簡単に説明する。

* `simplesrv`
    * `gen_server` ビヘイビアを使ったモジュールのテンプレート
* `simplenode`
    * リリース用のファイル群を作成するテンプレート
        * 10ファイル程作成される
    * 詳しくは[このあたり](https://github.com/rebar/rebar/wiki/Release-handling)
* `simplemod`
    * 単純なモジュールファイルのテンプレート
    * eunit用のテストファイルのテンプレートも一緒に作成してくれる
* `simplelib`
    * ライブラリ用の `src/${APPNAME}.app.src` とソースファイルのテンプレート
* `simplefsm`
    * `gen_fsm` ビヘイビアを使ったモジュールのテンプレート
* `simpleevent`
    * `gen_event` ビヘイビアを使ったモジュールのテンプレート
* `simpleapp`
    * アプリケーション用の `src/${APPNAME}.app.src src/${APPNAME}_app.erl src/${APPNAME}_sup.erl` のテンプレート
* `ctsuite`
    * Common Test用のSUITEのテンプレート
* `basicnif`
    * NIFを使うモジュールのテンプレート

良く使いそうなのは `simplemod simplesrv` あたりだろうか…。

## 実際に使う方法

実際に使うには、 **./rebar create template=テンプレート名 変数** で使うことができる。
テンプレート名は `list-templates` で存在するテンプレートの名前(ex. `simplemod` )で、変数は `list-templates` の `variables` にある変数(ex. `modid` )である。変数についてはデフォルト値が設定されているので、省略することもできる。
カレントディレクトリの直下にファイル・ディレクトリを作成するので、作成したいディレクトリに移動してから使う必要がある。
`src` 等のディレクトリはなくても勝手に作ってくれる。

##### 動作例

```shell-session
$ ./rebar create template=simplemod modid=my_module
==> ${APPNAME} (create)
Writing src/my_module.erl
Writing test/my_module_tests.erl
$ ls src
my_module.erl
$ ls test
my_module_tests.erl
$
```

# 独自テンプレートの作り方

独自テンプレートを作るのも簡単である。
最低限、 `${TEMPLATENAME}.template` ファイルがあればそれでよい。
templateファイルは以下のように記述する。

```erlang
{variables, [{modid, "mymod"}, {yearno, "2014"}, {author, "KOU_CHANG"}]}.
{template, "stdmod.erl", "src/{{modid}}.erl"}.
{template, "stdmod_tests.erl", "test/{{modid}}_tests.erl"}.
```

* `{variables, Variables}`
    * Variablesは `list()` で取り得る変数を `tuple()` で指定する。
        * 1つ目の値は **変数名** (ex. `modid` )
        * 2つ目の値は **デフォルト値** (ex. `"mymod"` )
* `{template, Template, OutputPath}`
    * `Template` を `OutputPath` に作成
        * `OutputPath` には `Variables` の値を埋め込める
            * 埋め込むには `src/{{}}` で囲む
                * ex. `{{modid}}`
        * 同様に `Template` のファイル内にも `{{}}` の形式で値を埋め込める
            * ex. `-module({{modid}}_tests).`
* 他、 `file, chmod` 等
    * `{file, Template, OutputPath}`
        * `Template` ファイルを `OutputPath` に作成
    * `{chmod, Mode::integer(), File}`
        * `FILE` の権限を `Mode` にする
            * ex. `{chmod, 8#744, "files/erl"}`
                * `files/erl` の権限を `744` にする

上記のようにtemplateファイルとテンプレートのソースファイル(上記、 `Template` )を作ったら、全部、ホームディレクトリ下の `~/.rebar/templates/` ディレクトリに置く。
そうすると、正しく置けていると、 `./rebar list-templates` でテンプレートを取得することができ、 `./rebar create` でtemplateが使えるようになる。

# 最後に

templateはGitHubにもいくつか落ちているので使用・参考にして下さい。

* Search rebar template - GitHub
    * https://github.com/search?utf8=%E2%9C%93&q=rebar+template&type=Repositories&ref=searchresults

**テンプレートを使いこなして楽しいErlangコーディング人生を送りましょう！！**