process dictionary
erlangはプロセスごとにディクショナリを持っている.putで値をいれ,getで取得し,eraseで消す.
1> put(foo, {1, 2, 3}).
undefined
2> put(bar, "hoge").
undefined
3> get(foo).
{1,2,3}
4> get(bar).
"hoge"
5> get().
[{foo,{1,2,3}},{bar,"hoge"}]
6> put(bar, "fuga").
"hoge"
7> get(bar).
"fuga"
8> erase(foo).
{1,2,3}
9> get(foo).
undefined
10> erase().
[{bar,"fuga"}]
11> get().
[]例えばrandomなどで利用されている.randomはseed()で種をセットする.
1> random:seed().
{3172,9814,20125}その後,random:uniform()で乱数を取得できる
2> lists:map(fun(X) -> random:uniform() end, lists:seq(1,10)). [9.23009e-2, 0.443585, 0.723040, 0.945816, 0.501491, 0.311327, 0.597448, 0.915656, 0.666957, 0.477121] 3> lists:map(fun(X) -> random:uniform(10) end, lists:seq(1,10)). [6,2,3,7,2,6,3,5,5,1]
random:seed()で帰ってくる3つの整数値が乱数生成器の状態を表しているのだが,これは内部の状態を表しているので,引数に渡したくない.そのためprocess dictionaryを用いて実装されている.
ソースは以下のようになっている.
seed()はseed(A1,A2,A3)を呼び出し,状態をrandom_seedとして登録する.
seed(A1, A2, A3) -> put(random_seed, {abs(A1) rem 30269, abs(A2) rem 30307, abs(A3) rem 30323}).
uniformを実行するときはrandom_seedを取得して乱数値を計算する
uniform() -> {A1, A2, A3} = case get(random_seed) of undefined -> seed0(); Tuple -> Tuple end, B1 = (A1*171) rem 30269, B2 = (A2*172) rem 30307, B3 = (A3*170) rem 30323, put(random_seed, {B1,B2,B3}), R = A1/30269 + A2/30307 + A3/30323, R - trunc(R).