Я пытаюсь обойти проблему с file:consult/1, не позволяющим кортежи с забавой в них как в этом примере:
{add_one, fun(X) -> X+1 end}.
Для обхождения этого, я рассматриваю запись забавы в строке и оценки ее
{add_one, "fun(X) -> X+1 end"}.
Вопрос. Как я преобразовываю строку в забаву?
parse_fun_expr(S) ->
{ok, Ts, _} = erl_scan:string(S),
{ok, Exprs} = erl_parse:parse_exprs(Ts),
{value, Fun, _} = erl_eval:exprs(Exprs, []),
Fun.
]
[] Обратите внимание, что вам нужен период в конце выражения fun, например []S = "fun(X) -> X + 1 конец."[
].[
file:script/1
почти делает то, что вы хотите - он вычисляет серию выражений erlang из файла и возвращает последний результат. Вы могли бы использовать его вместо файла -консультация/1
, но необходимо изменить формат файла с "term. term. term.", давая [термин, термин, термин]
на "[термин, термин, термин]", давая [термин, термин, термин]
- поместить в файл одно выражение вместо последовательности.
Хочу отметить, что ответ Зеда создает интерпретируемое веселье. Когда веселье вызывается, оно попадает в вычислитель, который начинает оценивать абстрактное синтаксическое дерево, возвращенное 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
, синтаксическое дерево было закрыто, а внутри erlang_eval было создано развлечение, как видно из информации модуля
.
Компилятор erlang можно использовать для создания скомпилированного модуля во время выполнения, а указателем на него является compile:forms/2 и code:load_binary/3. Но подробности этого, вероятно, должны войти в другой вопрос о переполнении стека.
.] Может быть, используя [] erl_eval[
] [][] модуль [][]? [