% (1).配置文件可以很方便地用 JSON 数据表示。
% 请编写一些函数来读取包含 JSON 数据的配置文件,
% 并将它们转换成 Erlang 的映射组。
% 再编写一些代码,对配置文件里的数据进行合理性检查。
注意:Erlang 并没有自带 Json 序列化函数
老爷子写的书上明明有,你说没有?戳 这里
这点也坑了我一下。
不过 StackOverFlow 答主给我们列出了两个 Erlang Json 序列化工具。
戳 jiffy 和 jsx
这里我用 rfc4627 这个序列化工具来解答,rfc4627 使用起来非常简单。
而且,据说 rfc4627 Json解析原本是想加入 Erlang 库里的。
先看下简单使用吧,git 上clone
下来后,当作我们平时写的模块用就好了。
其实内部有这些函数
% 配置文件比较简单,如下,如果是复杂的配置文件,代码需要更改
% {"cpu":"8"}
% {"memory":"8G"}
% {"disk":"1T"}
-module(parseFile).
-export([parse_file/1]).
-import(rfc4627, [decode/1, encode/1]).
parse_file(File) ->
case file:open(File, read) of
{ok, FileFd} -> parse_file(FileFd, io:get_line(FileFd, "Read a line"), #{});
{error, Reason} -> io:format("parse_file/1 error:~p~n", [Reason])
end.
% 非文件结尾
parse_file(FileFd, Line, X) when Line =/= eof ->
case rfc4627:decode(Line) of
{ok, {obj, [{Key, Value}]}, []} -> parse_file(FileFd, io:get_line(FileFd, "Read a line"), X#{Key => Value});
{error, Reason} -> io:format("parse_file/3 error:~p~n", [Reason])
end;
% 读到文件结尾
parse_file(FileFd, Line, X) when Line =:= eof ->
file:close(FileFd),
X.
注意:配置文件要是 .json 结尾,普通文件存储 json 格式有许多奇怪的问题。
% (2).编写一个 map_search_pred(Map, Pred) 函数,
% 让它返回映射组里第一个符合条件的 {Key, Value} 元素
% (条件是 Pred(Key, Vaule) 为 true)。
-module(mapsearchpred).
-export([map_search_pred/2, pred/2]).
map_search_pred(Map, Pred) ->
map_search_pred(Map, maps:keys(Map), Pred).
map_search_pred(Map, [Key|T], Pred) ->
case pred(Key, maps:get(Key, Map)) of
true -> {Key, maps:get(Key, Map)};
false -> map_search_pred(Map, T, Pred)
end;
map_search_pred(Map, [], Pred) ->
io:format("not found~n").
% 比较函数
pred(Key, Value) ->
case (Key =:= Value) of
true -> true;
false -> false
end.
% (3).高级练习:查找 Ruby 散列类的手册页。制作一个模块,
% 加入这个 Ruby 类里你认为适合的 Erlang 方法。
% 这里我简单实现一个 计算元祖中元素出现的次数。
开放性题目,感兴趣大家自己去查查吧~。