モダンErlang/OTP開発環境 2013

とりあえずモダン○○といっとけばいいかなと思ったが、モダニズムとか言ってた頃からモダンという言葉には「最近の」「ナウい」とかその程度の意味しかないのでそんなにありがたい話ではないことにご注意いただきたい。大正とか昭和初期のオバちゃんが「いや〜モダンやわぁ〜」とか言ってたのと同じだ。今ではもうばあちゃんだな。

エディタ

世間にはエディタを巡って宗教対立が発生し、場合によっては宗教戦争になるそうだがErlang/OTPの世界においてはそれは起き得ない。なぜならEmacsがデフォルトの開発環境として推奨されており、メジャーモードが処理系のディストリビューションに含まれているからだ。さまざまな便利ショートカットが用意されているので M-x tempo- と入れて補完されるものを眺めるとよいだろう。

パスを通して

(require 'erlang-start)
(require 'erlang-flymake)

してやるとよい。

ちなみにVimEclipseと同じくらいマイノリティだ。これらのマイノリティを採用する場合は、Emacsに比べて10〜100倍ほど生産性に差が出るレベルでないとやめた方がよい。

ソースコードを読むとき、ちゃんとしたい人はGTAGSか、erlcscopeがよいだろう。erlcscopeはcscopeとは別の実装だが、Emacsのcscope.elと相性がよいので僕もたまに使う。たまに使うが、普段はgrepだ。

OS

Erlang/OTPは現在、Linuxが最もメジャーなOSだろう。商用環境で次に多いのはSolaris系のOSだ。開発環境の場合はMacOSを使える場合もあるが、dtraceを使えるようになる代わりに本番環境との微妙な違いに悩むことが多いだろう。NIFなどのC拡張があると余計に面倒が増える。私は基本的にLinuxを使っている。ちなみにソースをみるとわかるが、他にもマニアックな*nix系OSに対応している。
BSD系もユーザーがいないことはない。Windowsでも動かないことはないが茨の道だろう。

コンパイラと処理系

Ericssonが出しているもの以外の処理系では、Triforkが公開しているErjangが有名だ。組み込み向けのものもあったように記憶している。真面目にErlang/OTPを使いたい場合はローカルで複数のバージョンを用意しておくことをすすめる。rbenvのようなものとしてはkerlがあるが、rbenvとちがってRubygemsのようなエコシステムはないので大して役に経たない。

最初はOSのディストリビューションが提供するものでもよいかもしれないが、本気で使うならソースから入れておくのがよいだろう。僕は /usr/local/erlang 以下に

$ ls /usr/local/erlang
R14B04  R15B01  R15B01.zdss  R15B03  R16B  R16B01  eqc

と、prefix指定したものをいろいろと入れている。PATHをbinに通すだけで使い分けられるので便利だ:

$ export PATH=/usr/local/erlang/R16B01/bin:$PATH

コンパイルオプションはいつもこんな感じだ:

MacOS

$ ./configure --enable-darwin-64bit --disable-hipe --enable-vm-probes --with-dynamic-trace=dtrace --prefix=/usr/local/erlang/R16B01

Linux

$ sudo aptitude install xsltproc fop libssl-dev
$ ./configure --enable-m64-build --disable-hipe  --prefix=/usr/local/erlang/R16B01

この過程でncurses-devなど必要なものを指摘されるので注意しておくこと。wxは別になくてもよいだろう。javaがないとwithout指定か何かが必要だった気がするが、特に気にしてないので記憶していない。

manpagesも、ソースから入れておくとよい。とんぷー氏のブログ記事が参考になるがここにも転載しておく。

$ make docs
$ make install-docs

これを動かすためにはfopやxsltprocなどいろいろと必要になるので都度インストールすること。

ビルドツール

ビルドツールの選定ほど面倒なことはない。しかしErlang/OTPではrebar一択だ。もしもautomakeなど、rebar以外のツールを使っているプロジェクトがあったら、それは少しあやしいので眉に唾をつけるとよいだろう。rebarをちいさなMakefileでラップするのが一般的だ。Makefileのサンプルもあるので参考にするとよい。

rebarは依存ライブラリをバージョンつきで指定することができる。これはとても便利だが、ダイヤモンド依存になったときに依存しているバージョンが異なる場合があるので注意すること。

VCS

rebarがそのサービスをサポートしているものを使うとよい。git, hgなどいくつかあるので、github, bitbucketなどのレポジトリを依存ライブラリとしてバージョン指定するとよいだろう。

テスト環境

ユニットテストはeunitかct(common tests)で書くのが一般的だ。テスト用のライブラリはmeck, properなどが代表的だ。Dialyzerという静的な型解析ツールもある。テストは分野によって書き方や使い方が全然違うので自分に合ったものを模索するしかない。

僕の会社ではeunitでQuickCheck (プロプラ)を流して、結合は riak_test というのを使っている。

人によってはTravis-CIやdrone.ioなども合わせて使うとよいだろう。この辺はErlang/OTPに独特ということはあまりない。

パッケージング

Erlang/OTPはそれ自体、パッケージングやリリースのための仕組みが沢山ある。交換機は無停止でシステムを更新する必要があったから、そういったところも処理系に組み込まれている…のだが、これが滅法使いにくい。なので、rebarがこれをサポートするコマンドを作って、tarball一発まで作れるようになっている。これが便利なのは、Erlangの処理系もリリースパッケージに一緒に入れてしまうので、本番環境で特に環境を作る必要がほとんどないためだ。Erlangを頑張ってインストールする必要はない(goみたいですごいでしょ!)。

しかし、これだけだとtarballなど独特の仕組みになってしまい、設定ファイルなどもまだ扱いにくい。そこで登場するのが、 node_package だ。これを使うことで、APT, yum, SmartOS, ports など様々な環境に向けたリリースパッケージを構築してくれる。設定ファイルやログの出力など、それぞれのOSの流儀に合ったものにしてくれる。コマンドひとつで.debパッケージを作るの、昔からの夢だったんだ…!

ライブラリ

これ!といった定番がいくつかあるので…とはいえ、いろいろありすぎて面倒なのでパス。

ドキュメント

edocというのがあり、これもrebarを使えば一発でHTMLを吐いてくれる。使っている人もいるし使っていない人もいる。たいていはREADME.mdで済ませてしまっている。

デバッガ

基本的には printf というデバッガが最もよく使われている。いちおう、C拡張などをテストするため gdb も使えたりするのだが… distel は emacs と相性がよく昔から使われている。また、最近では redbug というツールがとてもよい。これは予めプロダクションシステムに仕込んでおけば、サービスを止めずにコールフローを追ったりフックを仕掛けたりやめたりできる優れものなので使い方を覚えておくとよいだろう。

まとめ

erlang-users.jpというサイトを最近復活させたので、ヒマがあったらそちらを覗いてみると新しい情報がなにか出ているかも?!