やっと6章まで読み終わった。いよいよ7章から並行処理に入る。
ところで6章には「コマンドライン引数を使うプログラム」の例として階乗を計算するプログラムが載っているのだが、これをそのまま実行すると引数の数が合わない場合にクラッシュダンプを吐く。流石にもうちょっと何とかならないかと思って調べてみたところ、次のようなことが分かった:
- コマンドライン引数の数によって呼び出される関数が変わる。erl -s module func と指定した場合、コマンドライン引数を一つも与えなかった場合は module:func/0 が、一つ以上与えた場合は module:func/1 が呼び出される。
- module:func/1の引数はアトムのリストである。
- escriptではこの差異を吸収して、アトムをリスト(文字列)に変換した上で main/1 を呼び出している。
ということで escript の動作にあわせて次のようにしてみた。
-module(fac2). -export([run_main/0, run_main/1]). run_main() -> main([]). run_main(L) -> main(lists:map(fun atom_to_list/1, L)). main([A]) -> I = list_to_integer(A), F = fac(I), io:format("factorial ~w = ~w~n", [I, F]), init:stop(); main(_) -> io:format("Usage: ~p:rum_main <num>~n", [?MODULE]), init:stop(). fac(0) -> 1; fac(N) -> N * fac(N-1).
起動は erl -noshell -s fac2 run_main とする。
…
それと、6章にはMakefieのテンプレートも載っているのだが、その中の .SUFFIXES および .erl.beam といったターゲット名は古い形式の定義らしい。新しい形式では型ルールを使って次のように書けば良いようだ。
%.beam: %.erl
erlc -W $<