質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Elixir

Elixirは、並列処理や関数型に特化した、Erlang VM (BEAM) 上で動作する汎用プログラミング言語です。分散システム、耐障害性、ソフトリアルタイムシステムなどの機能を持ちます。

Q&A

解決済

1回答

1650閲覧

Elixirでatomをキーに持つマップをファイルに保存したい

退会済みユーザー

退会済みユーザー

総合スコア0

Elixir

Elixirは、並列処理や関数型に特化した、Erlang VM (BEAM) 上で動作する汎用プログラミング言語です。分散システム、耐障害性、ソフトリアルタイムシステムなどの機能を持ちます。

0グッド

0クリップ

投稿2019/06/29 09:24

やりたいことはタイトルの通りで,どうするのが良いのかわからず困っています.
%{key1: "value1", key2:"value2"}
のようなマップをリストにしたものをファイルに保存しようとしています.
イメージとしてはデータベースのレコードを保存です.

Poisonを使ってJSON形式にして保存・読み出しはできたのですが,これを用いて保存してしまうと,Atomのキーが文字列として取り扱われるので,次に読み出したときには文字列のキーとして読み込まれてしまいます.このような場合,どう取り扱うのが正しいのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Poisonならdecodeの際にキーをatomに変換するkeys: :atoms!オプションを使うといいでしょう。

elixir

1iex> map = %{key1: "value1", key2: "value2"} 2%{key1: "value1", key2: "value2"} 3 4# mapをjson文字列に変換する 5iex> json = Poison.encode!(map) 6"{\"key2\":\"value2\",\"key1\":\"value1\"}" 7 8# json文字列をmapに変換する。その際、キーはatomにする 9iex> Poison.decode!(json, %{keys: :atoms!}) 10%{key1: "value1", key2: "value2"}

別の方法として、JSONではなく、Erlang組み込みのシリアライズフォーマットであるErlang external term formatを使うこともできます。

JSON(JavaScript Object Notion)は元々はJavaScriptのオブジェクトをシリアライズするために考案されたフォーマットですので、ErlangやElixirのatomのようなJavaScriptにはないデータ型は表現できません。Erlangは分散システムの開発が得意な言語ですので、ノード間でErlangのデータ(Erlang termと呼ばれます)を送受信するための専用のシリアライズフォーマットが昔から言語に組み込まれています。このフォーマットならmapだけでなく、atomなども表現できます。

ただし、JSONは人間が直接読めるフォーマットですが、Erlang external term formatはbinary(バイト列)なので人間には読めません。その代わり、全てのErlang termが表現できます。

elixir

1iex> map = %{key1: "value1", key2: "value2"} 2%{key1: "value1", key2: "value2"} 3 4# Erlang termをシリアライズする 5iex> bin = :erlang.term_to_binary(map) 6<<131, 116, 0, 0, 0, 2, 100, 0, 4, 107, 101, 121, 49, 109, 0, 0, 0, 6, 118, 97, 7 108, 117, 101, 49, 100, 0, 4, 107, 101, 121, 50, 109, 0, 0, 0, 6, 118, 97, 8 108, 117, 101, 50>> 9 10# Erlang termをデシリアライズする 11iex> :erlang.binary_to_term(bin) 12%{key1: "value1", key2: "value2"} 13 14# binaryを印字可能な文字に変換するにはBase.encode16が使える 15iex> encoded = Base.encode16(bin) 16"8374000000026400046B6579316D0000000676616C7565316400046B6579326D0000000676616C756532" 17 18iex> Base.decode16(encoded) 19{:ok, 20 <<131, 116, 0, 0, 0, 2, 100, 0, 4, 107, 101, 121, 49, 109, 0, 0, 0, 6, 118, 97, 21 108, 117, 101, 49, 100, 0, 4, 107, 101, 121, 50, 109, 0, 0, 0, 6, 118, 97, 22 108, 117, 101, 50>>}

投稿2019/07/02 01:52

tatsuya6502

総合スコア2035

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問