Frage

Hello awesome erlang community!

I've got

  • an erlang module that receives erlang code from the user,
  • it executes the erlang expression
  • and returns the results to the user.

Kind of like a shell. Except, there is no

  • variable bindings
  • or command history.

I'm wondering if there is a complete and utter lazy way of going about implementing the bindings/history by:

  • opening up an erlang shell in the background
  • keeping it alive
  • and communicating with it.

i.e. Send the shell the commands and it sends the results back to my module

I can't seem to find a way.

Is this possible? Or am I doomed to implement it myself?

Thanks :)

War es hilfreich?

Lösung

After reading through the erlang docs for erl_eval, I've come up with a solution that was suitable for my project (Erlang language kernel for IPython). I'd like to share, in case anyone else has the same issue.

Variable Bindings

To execute erlang code, I created a function to do so. Whilst keeping track of variable bindings.

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

Here, I pass the code (string) and the bindings (empty list to begin with).

The function executes the erlang expression and its bindings. It then returns the execution result (value) and the new list of variable bindings (old variable bindings + any new variables that may have been assigned during code execution).

From here, you should be able to keep track of code execution and bindings from your calling function.

Code History

If you would like to implement code history, you could change the Code variable to a list of strings. For example:

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

Before you call the execute function you'd obviously have to append the code to be executed to the Code list.

NewCodeList = lists:append(NewCode, OldCodeList),
% Execute code at head of list
{ok, Value, NewBindings} = execute(NewCodeList, Bindings).

Hope this helps :)

Andere Tipps

You need use erlang-history erlang-history

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top