mochijson2
Erlang で JSON からデータを取り出したくて、mochijson2 に辿り着いた。
https://github.com/bjnortier/mochijson2
やりたかったことは、Google Geocoding APIを使って、住所から座標を取り出すこと。
説明に書いてあるとおり、
http://maps.googleapis.com/maps/api/geocode/json?address=東京都新宿区
のように検索すると、結果が JSON 形式で返ってくる。
{ "results" : [ { "address_components" : [ { "long_name" : "新宿区", "short_name" : "新宿区", "types" : [ "locality", "political" ] }, { "long_name" : "東京都", "short_name" : "東京都", "types" : [ "administrative_area_level_1", "political" ] }, { "long_name" : "日本", "short_name" : "JP", "types" : [ "country", "political" ] } ], "formatted_address" : "日本, 東京都新宿区", "geometry" : { "bounds" : { "northeast" : { "lat" : 35.7298939, "lng" : 139.7451615 }, "southwest" : { "lat" : 35.6731516, "lng" : 139.6732487 } }, "location" : { "lat" : 35.6938401, "lng" : 139.7035494 }, "location_type" : "APPROXIMATE", "viewport" : { "northeast" : { "lat" : 35.7298939, "lng" : 139.7451615 }, "southwest" : { "lat" : 35.6731516, "lng" : 139.6732487 } } }, "types" : [ "locality", "political" ] } ], "status" : "OK" }
この結果が 下記コードの Body に入っている。
構造としては、
1. results の中の配列の一番目の塊の中
2. geometry というキーのバリューの中
3. location というキーのバリューの中
4. lat, lng というキーの値がそれぞれ緯度経度
これを順に辿っていくことになる。
Decoded = mochijson2:decode(Body), {struct, Results} = Decoded, Results2 = proplists:get_value(< <"results">>, Results), [H, T] = Results2, {struct, Items} = H, Geo = proplists:get_value(< <"geometry">>, Items), {struct, Locs} = Geo, Loc = proplists:get_value(< <"location">>, Locs), {struct, Latng} = Loc, Lat = proplists:get_value(< <"lat">>, Latng), Lng = proplists:get_value(< <"lng">>, Latng),
ポイントとしては、
・mochijson2:decode から値を取り出すと {struct, 本体} という形なので、本体のほうを分解していく
・キーの名前を指定するときは、バイナリ形式で < <"キー">> という形で書く
・配列の先頭を取り出すときに [H, T] という形に代入すると H が先頭(Head)
といったところだったかな。
参考になったサイトは、
Destructuring JSON in Erlang Made Easy
である。
最初にコマンドラインでちゃんと分解してみてから、アプリのコードに組み込むべし。
このあと住所の投げ方によって返ってくる形が違うことがわかり、If文とかを追加してちょっと複雑になった。
そんなこんな、誰が使うんだろうね・・・
Erlang が流行ってるのかどうか、全然知らない。
Erlang
技術的に使わなければならない明確な理由は見えていないけど、仕事で使い始めた。
Erlang というプログラミング言語。
並列処理に強いらしい。
・行の区切りは , (カンマ)
・節の区切りは ; (セミコロン)
・命令の終わりは . (ドット)
という直感的ではない言語なので、まだ好きになれない。
例えば、こんな感じになるのだが、end. の前が ; で終わらないのがなんかイヤ。
logout('GET', []) -> Response = api:logout(boss_session:get_session_data(BossSessionID, sessionID)), case Response of ok -> boss_session:delete_session(BossSessionID), {redirect, "login"}; {error, Reason} -> {ok, {error, Reason}} end.
他にも、
・変数は大文字で始まる
・変数は再代入できない
・関数の最後にアクセスした値がそのままreturnされる
・コメントアウトは % (パーセント)
・文字列の連結は ++ (プラス2つ)
・改行文字が ~n などニョロ
という書き方上の違和感はたくさんある。
いちばん大きい特徴は、値をバイナリに変換してから変数に渡さないといけないことかもしれない。
例えば、日本語を扱うとき、
unicode:characters_to_binary(FirstName)
のように一度バイナリに変換しないとエラーになる。
バイナリの値は
< < >>
で囲まれて表現されるらしい。
まだ少ししか書いてないけど、やっぱりまだ慣れてない。