你好,很棒的 erlang 社区!
我有
- 一个从用户接收erlang代码的erlang模块,
- 它执行 erlang 表达式
- 并将结果返回给用户。
有点像贝壳。除了,没有
- 变量绑定
- 或命令历史。
我想知道是否有一种完整且完全懒惰的方式来实现绑定/历史:
- 在后台打开一个 erlang shell
- 让它活着
- 并与之交流。
即向shell发送命令并将结果发送回我的模块
我似乎找不到方法。
这可能吗?还是我注定要自己实施?
谢谢 :)
在阅读了erl_eval的 erlang 文档后,我想出了一个适合我的项目的解决方案(用于 IPython 的 Erlang 语言内核)。我想分享一下,以防其他人有同样的问题。
为了执行 erlang 代码,我创建了一个函数来执行此操作。同时跟踪变量绑定。
execute(Code, Bindings)->
{ok, Tokens, _} = erl_scan:string(Code),
{ok, [Form]} = erl_parse:parse_exprs(Tokens),
{value, Value, NewBindings} = erl_eval:expr(Form, Bindings),
{ok, Value, NewBindings}.
在这里,我传递了代码(字符串)和绑定(以空列表开头)。
该函数执行 erlang 表达式及其绑定。然后它返回执行结果(值)和新的变量绑定列表(旧变量绑定 + 代码执行期间可能已分配的任何新变量)。
从这里,您应该能够跟踪调用函数的代码执行和绑定。
如果您想实现代码历史记录,可以将Code变量更改为字符串列表。例如:
execute([Code|Tail], Bindings)->
{ok, Tokens, _} = erl_scan:string(Code),
{ok, [Form]} = erl_parse:parse_exprs(Tokens),
{value, Value, NewBindings} = erl_eval:expr(Form, Bindings),
{ok, Value, NewBindings}.
在调用执行函数之前,您显然必须将要执行的代码附加到代码列表中。
NewCodeList = lists:append(NewCode, OldCodeList),
% Execute code at head of list
{ok, Value, NewBindings} = execute(NewCodeList, Bindings).
希望这可以帮助 :)
你需要使用 erlang-history erlang-history