このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

Erlang実験室:ビヘイビアを自分で定義する方法

Erlang/OTPでは、gen_server(Generic Server Behaviour)のような便利なフレームワークが用意されています。これは、ビヘイビア(behaviour)という概念に基づいています。ビヘイビアを使ったプログラムは、

  1. ビヘイビア実装モジュール(ライブラリ側)
  2. コールバック・モジュール(ユーザー定義側)

の2つのモジュールから構成されます*1

例えば、gen_serverのコールバック・モジュールでは、自分がgen_serverの規約に従うことを次の形で宣言します。


-behaviour(gen_server).
そして、必要なコールバック関数をエクスポートします。

-export([init/1, terminate/2, handle_call/3]).
-export([handle_cast/2, handle_info/2, code_change/3]).

さて、「ビヘイビアを自分で定義するにはどうしたらいいのだろうか?」と疑問だったんですが、gen_serverのソースを見たらすぐわかりました。例題として、状態マシンのフレームワークを作るとすれば、状態マシンのビヘイビア実装モジュールで次のように書きます。


-module(state_machine).

-export([behaviour_info/1]).

behaviour_info(callbacks) ->
[
% is_symbol(term()) -> boolean()
{is_symbol, 1},
% is_acceptable_symbol(State, term()) -> boolean()
% State = term()
{is_acceptable_symbol, 2},

% init() -> State
{init, 0},
% input(State, term()) -> NewState
{input, 2},
% is_final(State) -> boolean()
{is_final, 1}
];
behaviour_info(_Other) ->
undefined.

要するに、期待するコールバック関数達を {関数名, アリティ} の形で並べるだけです。形式上は、behaviour_info/1という関数を定義しますが、意味的にはある種のインターフェース宣言です。この宣言に対応する関数定義がコンパイルされ、モジュールのBEAMファイルに入ります。

コールバック・モジュール側で -behaviour(state_machine). と書くと、コンパイラはstate_machineモジュールのbehaviour_info/1を呼んで取得した情報をもとにチェックをします。ビヘイビアに宣言された関数がないと警告しますが、エラーにはなりません。

*1:2つ以上のモジュールで構成してもよいが、複雑化するから好ましくないだろう。