タプルを使用した関数呼び出し

「Erlang dict」で検索すると最初に引っかかるページ「Erlang クエックブック」。このページにおいてdictの使い方は次のように説明されている:

D1 = dict:new().                            % 作成
D2 = D1:store(key1, value1).                % キーと値のペアを入れる

新しく作った辞書を「モジュール名として」指定して、dict モジュールの関数を呼び出している。まるでオブジェクト指向におけるメソッド呼び出しのような奇妙な記法だが、確かにこれで動作する。

なぜだろう?

いろいろと調べた結果、これは dict に特有の話ではなく、モジュール名としてタプルを指定した場合の特殊な動作だということが分かった(dict モジュールは個々の辞書をタプルとして表現している)。Mod:Fun(Arg1,..ArgN) の評価を疑似コードで書くと次のようになる:

{Mod,Fun,Args} when is_tuple(Mod), is_atom(element(1, Mod)) ->
	erlang:apply(element(1, Mod), Fun, Args ++ [Mod])

次のように動作を確かめることができる。

erl> M1 = {erlang, 1, 2, 3}.
{erlang,1,2,3}
erl> M1:tuple_to_list().
[erlang,1,2,3]

問題は、この動作が公式なドキュメントのどこにも書いていないということだ。少なくとも私は見つけられなかった。

これとよく似た例として、{Module, FunctionName} という形式のタプルが Module:FunctionName として評価されることはいくつかのドキュメントで触れられており、「非推奨」だとされている。よってこれも既に使われなくなった、古い形式の呼び出し方だということだろうか……?

Leave a Reply