Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang -- How to convert a fun() object to a String

Tags:

erlang

Is there a straightforward way to convert an Erlang fun to a string? A call to io_lib:format only prints the function reference, e.g. something like "#Fun<erl_eval.20.67289768>". For example, I'd like to be able to do this:

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

I'm looking for how to implement fun_to_str. In javascript, some interpreters have a .toSource() function that can be called on any object, including functions, that print their string representation. Any info is appreciated, thanks.

like image 807
Travis Webb Avatar asked Mar 09 '11 18:03

Travis Webb


2 Answers

First, get the environment variables for the fun (which includes the abstract code):

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}]}]}]}]}

Pretty print the abstract code using 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

(You have to add {'fun', 1, {clauses, ...}} around it to make it a complete Erlang expression)

like image 73
Adam Lindberg Avatar answered Nov 20 '22 18:11

Adam Lindberg


You might be able to use erlang:fun_info/2 for that, atleast i get some information from the shell when doing

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>

You want the last list with the clause atom and then pretty print it using for instance erl_pp

like image 3
Lukas Avatar answered Nov 20 '22 19:11

Lukas