将字符串转换为乐趣

时间:2010-01-05 20:16:37

标签: erlang

我正在尝试解决文件问题:咨询/ 1不允许元组在其中有趣,如下例所示:

{add_one, fun(X) -> X+1 end}.

为了解决这个问题,我正在考虑在字符串中编写乐趣并对其进行评估

{add_one, "fun(X) -> X+1 end"}.

问题是。如何将字符串转换为有趣的?

5 个答案:

答案 0 :(得分:11)

parse_fun_expr(S) ->
  {ok, Ts, _} = erl_scan:string(S),
  {ok, Exprs} = erl_parse:parse_exprs(Ts),
  {value, Fun, _} = erl_eval:exprs(Exprs, []),
  Fun.

请注意,您需要在乐趣表达结束时使用句号,例如: S = "fun(X) -> X + 1 end."

答案 1 :(得分:6)

file:script/1几乎可以做你想要的 - 它从文件中计算一系列erlang表达式并返回最后的结果。您可以使用它代替file:consult/1,但您需要从“term.term.term”更改文件的格式。将[term, term ,term]提供给“[term,term,term]。”给[term, term, term] - 在文件中放置一个表达式而不是序列。

答案 2 :(得分:2)

我想指出,Zed的回答创造了一种解释乐趣。当调用fun时,它进入评估器,评估器开始评估它捕获的erl_parse:parse_exprs/1返回的抽象语法树。看看创造的乐趣:

11> erlang:fun_info(Fun, env).
{env,[[],none,none,
      [{clause,1,
               [{var,1,'X'}],
               [],
               [{op,1,'+',{var,1,'X'},{integer,1,1}}]}]]}
12> erlang:fun_info(Fun, module).
{module,erl_eval}

可以看到它已经关闭了解析后的抽象语法树,如env信息中所示,并且在module信息中看到的erlang_eval内部创建了一个有趣的乐趣。

可以使用erlang编译器在运行时创建编译模块,指向它的指针是compile:forms/2code:load_binary/3。但其中的细节可能会进入另一个stackoverflow问题。

答案 3 :(得分:0)

也许可以使用erl_eval module

答案 4 :(得分:0)

2> F =fun(Str,Binding) ->
{ok,Ts,_} = erl_scan:string(Str),
Ts1 = case lists:reverse(Ts) of
          [{dot,_}|_] -> Ts;
          TsR -> lists:reverse([{dot,1} | TsR])
      end,
{ok,Expr} = erl_parse:parse_exprs(Ts1),
erl_eval:exprs(Expr, Binding) end.
#Fun<erl_eval.12.111823515>
3> F("A=23.",[]).
{value,23,[{'A',23}]}

5> F("12+B.",[{'B',23}]).
{value,35,[{'B',23}]}