我正在尝试编写一个通过 tcp 与客户端通信的简单服务器。我让它发送消息就好了,但现在我希望它把消息解释为 Erlang 数据类型。例如,假设它类似于 HTTP(它不是)并且我想从客户端发送{get, "/foo.html"}
并让服务器将其解释为包含原子和列表的元组,而不仅仅是一个大列表或二进制文件。
我可能最终会使用term_to_binary
and binary_to_term
,但调试基于文本的协议要容易得多,我希望能找到一个对列表更友好的版本。有没有藏在什么地方的?
我正在尝试编写一个通过 tcp 与客户端通信的简单服务器。我让它发送消息就好了,但现在我希望它把消息解释为 Erlang 数据类型。例如,假设它类似于 HTTP(它不是)并且我想从客户端发送{get, "/foo.html"}
并让服务器将其解释为包含原子和列表的元组,而不仅仅是一个大列表或二进制文件。
我可能最终会使用term_to_binary
and binary_to_term
,但调试基于文本的协议要容易得多,我希望能找到一个对列表更友好的版本。有没有藏在什么地方的?
您可以通过以下方式将字符串解析为表达式(类似于file:consult
):
% InputString = "...",
{ok, Scanned, _} = erl_scan:string(InputString),
{ok, Exprs} = erl_parse:parse_exprs(Scanned),
{value, ParsedValue, _} = erl_eval:exprs(Exprs, [])
(见http://www.trapexit.org/String_Eval)
您应该能够使用或格式代码io_lib:format
将表达式转换为字符串,例如.~w
~p
io_lib:format("~w", [{get, "/foo.html"}])
我认为这不会很快,所以如果性能是一个问题,你可能不应该使用这样的字符串。
另请注意,这可能是不安全的,因为您正在评估任意表达式 - 如果您走这条路,您可能应该对中间输出进行一些检查。我建议查看结果erl_parse:parse_exprs
以确保它包含您感兴趣的格式(即,它始终是 {atom(), list()} 的元组),没有嵌入式函数调用。您应该能够通过模式匹配来做到这一点。