はじめに
みなさんErlang Term Storage(ETS)を使ってますか?
依存関係なしでElixirから利用できるので便利ですよね。
確かにETSの関数はちょっとクセがあるので使いにくい面もあります。
そこでElixirのMap風のインターフェイスでETSを使えるようにしたらもっと気軽にできるのではと思い、取り組んでみました。
ETSとは
気軽にETSを使う
- 最低限これだけあれば気軽にETSを使えます。
- あらかじめ名前付きのETSテーブルを作れるようにしておきます。
- 値の挿入と取得もモジュール経由ででき便利です。
自前のETSモジュールを作る
defmodule MyEts do
def init, do: :ets.new(__MODULE__, [:set, :named_table])
def get(key, default \\ nil) do
case :ets.lookup(__MODULE__, key) do
[] -> default
[{_, value} | _] -> value
end
end
def put(key, value), do: :ets.insert(__MODULE__, [{key, value}])
def delete(key), do: :ets.delete(__MODULE__, key)
end
テーブルを作る
MyEts.init()
テーブルに値を挿入
MyEts.put(:feeling, "awesome")
テーブルから値を取得
MyEts.get(:feeling)
テーブルから値を削除
MyEts.delete(:feeling)
その他の関数
- Erlangの公式ドキュメントにリストアップされています。
- Elixir Schoolにもサンプルコードがいくつか紹介されています。
- 個人的には
select
系の関数が興味深いです。
db = :ets.new(:example_db, [:set, :named_table])
for i <- 0..9, do: :ets.insert(db, [{i, i**2}])
# キーの範囲を指定して複数の値を取得
match_spec = :ets.fun2ms(fn { key, value } when key in 3..5 -> value end)
:ets.select(db, match_spec)
Match Spec
- Match Specと呼ばれるErlang独自のクエリ言語で検索できる仕組みがあります。
-
Match Specは自力で書いてもいいのですが、
:ets.fun2ms/1
関数(もしくはex2msというHexパッケージが提供するEx2ms.fun/1
マクロ)が便利です。 - ややこしいですが、慣れると楽しめそうです。
Erlangの:ets.fun2ms/1はElixirで使うとたまに謎のコンパイル関連エラーが出て怖いのでElixir用のex2msパッケージを使うと無難そうです。
# :ets.fun2ms(fn { key, value } when key in 3..5 -> value end)
[
{{:"$1", :"$2"},
[
{:andalso, {:is_integer, :"$1"},
{:andalso, {:>=, :"$1", 3}, {:"=<", :"$1", 5}}}
], [:"$2"]}
]
一例としてex_ratedというHexパッケージでは、ある条件で古いデータを消去する目的でMatch Specを使ってます。
エラー
- Erlang特有のわかりにくいエラーメッセージが出ることがあります。
# 2回同じ名前のテーブルを生成した場合に出るエラー
iex> :ets.new(:example_table, [:set, :named_table])
:example_table
iex> :ets.new(:example_table, [:set, :named_table])
** (ArgumentError) errors were found at the given arguments:
* 2nd argument: invalid options
(stdlib 4.0.1) :ets.new(:example_table, [:set, :named_table])
iex:2: (file)
DETS
- ETSがインメモリのデータストレージであるのに対して、DETSはディスクベースのストレージです。
- 関数はETSと似ています。
- ディスクベースなのでデータベースファイルを開いて、使用後に閉じる必要があります。
@zacky1972先生のvarious_map
さらに@zacky1972先生がさまざまなMapの実装をされています。
さいごに
Elixirを楽しみましょう!
各コミュニティの詳細は、「Elixirコミュニティの歩き方 -国内オンライン編-」をご覧ください
各種Elixirイベントの開催予定は、「Elixirイベントカレンダー」から確認/参加できます
ご参考までに