2007年5月9日水曜日

erlang その7

ets:new とその関連関数を使ってみる。
これらの関数はテーブルを作成して、そこに色々な要素を記録しておくために使われるようだ。
C++のstd::mapの高機能版のようなものか?

まず、テーブルを作成する。
第1引数はテーブルの名前で、第2引数はオプションを指定する。[]でデフォルトが利用される。
Pにはテーブル識別子(マニュアルではtid()と記載されている)が代入される。
1> P=ets:new(table1,[]).
16

次にこのテーブルの情報を見てみる。
2> ets:info(P).
[{memory,279},
{owner,<0.30.0>},
{name,table1},
{size,0},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]

マニュアルによるとmemory は 「The number of words allocated to the table.」
とのことなので、単位をbytesであるとはいえそうにない。
sizeはテーブルに記録されているオブジェクトの数で、今は空なので0になっている。

テーブルに要素を追加してみる。
3> ets:insert(P, {aaa}).
true

テーブルの情報をみると、
4> ets:info(P).
[{memory,289},
{owner,<0.30.0>},
{name,table1},
{size,1},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]

となっており、要素数が1増えている。
さらに追加してみると、
5> ets:insert(P, {bbb}).
true
6> ets:info(P).
[{memory,299},
{owner,<0.30.0>},
{name,table1},
{size,2},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]

要素数が2になった。また、memoryが10ずつ増えている。
もう少し短いatomを追加してみる。
7> ets:insert(P, {c}).
true
8> ets:info(P).
[{memory,309},
{owner,<0.30.0>},
{name,table1},
{size,3},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]

要素数が3になり、memoryは前と同様に10増える。

要素を順番に見ていくには、ets:first/1とets:second/2を使う。
まずets:first/1を使って、
9> ets:first(P).
c

最初の要素はcのようだ。次にets:next/2を使って、
cの要素の次に記録されている要素を順次取得する。
10> ets:next(P,c).
aaa
11> ets:next(P,aaa).
bbb
12> ets:next(P,bbb).
'$end_of_table'

テーブルの最後までくると、'$end_of_table'が返される。
これで終端かどうかが判断できる。

ところで、このテーブルの機能は便利なのだが
テーブルに記録した値は変更できてしまうことになる。
使い方によってはC言語っぽい書き方ができてしまいそうだ。

また、ets.erlによると、これらetsモジュールの関数の一部、
例えばnewやfirst, nextの実装はC言語でされているとのことだ。

0 件のコメント :