Erlang - Как преобразовать объект fun() в строку

Есть ли простой способ конвертировать Erlang fun в string? Вызов io_lib:format только для печати ссылки на функцию, например. что-то вроде "#Fun<erl_eval.20.67289768>". Например, я хотел бы иметь возможность сделать это:

1> Fun = fun() -> atom_to_list('hello world') end.
2> FunStr = fun_to_str(Fun).
"fun() -> atom_to_list('hello world') end."

Я ищу, как реализовать fun_to_str. В javascript некоторые интерпретаторы имеют функцию .toSource(), которая может быть вызвана для любого объекта, включая функции, которые печатают свое строковое представление. Любая информация оценивается, спасибо.

Ответы

Ответ 1

Во-первых, получите переменные окружения для развлечения (включая абстрактный код):

1> {env, [{_, _, _, Abs}]} = erlang:fun_info(Fun, env).                     
{env,[{[],
       {eval,#Fun<shell.21.83096281>},
       {value,#Fun<shell.5.83096281>},
       [{clause,1,[],[],
                [{call,1,{atom,1,atom_to_list},[{atom,1,hello_world}]}]}]}]}

Достаточно напечатать абстрактный код, используя erl_pp:

3> Str = erl_pp:expr({'fun', 1, {clauses, Abs}}).           
[[[["fun",
    [[[[["()"]," ->"],
       ["\n       ",
        [["atom_to_list",[[40,["'hello world'",41]]]]]]]]]]],
  [10,["end"]]]]
4> io:format([Str|"\n"]).
fun() ->
       atom_to_list('hello world')
end
ok

(Вы должны добавить вокруг него {'fun', 1, {clauses, ...}}, чтобы сделать его полным выражением Erlang)

Ответ 2

Возможно, вы сможете использовать erlang: fun_info/2 для этого, по крайней мере, я получаю некоторую информацию из оболочки при выполнении

1> erlang:fun_info(fun() -> test,ok end, env).
{env,[[],
     {value,#Fun<shell.7.37281544>},
     {eval,#Fun<shell.24.85590193>},
     [{clause,1,[],[],[{atom,1,test},{atom,1,ok}]}]]}
2>

Вы хотите получить последний список с атомом предложения, а затем довольно печатать его, используя, например, erl_pp