I have a generated string that contains the code for an erlang module.
Is there a way to compile the generated module straight from the string?
Or is there a way to convert the string into the format needed for compile:forms/1
?
Or will I 开发者_StackOverflow社区have to save it to a temp file first and then compile it with compile:file/1
?
Alternatively, I can add support to the compile module, but there must be a reason why the good people that write erlang haven't added it.
You need to scan your string into tokens, and then parse the tokens into forms. Unfortunately it is only possible to parse one form at a time, so you will need to either cut your string, or your tokens at form boundaries. Here is a short example:
% create tokens from strings containing forms
> {ok, MTs, _} = erl_scan:string("-module(z).").
> {ok, ETs, _} = erl_scan:string("-export([f/0]).").
> {ok, FTs, _} = erl_scan:string("f() -> hello_world.").
% tokens to erl_parse trees
> {ok,MF} = erl_parse:parse_form(MTs).
> {ok,EF} = erl_parse:parse_form(ETs).
> {ok,FF} = erl_parse:parse_form(FTs).
% compile forms to binary
> {ok, z, Bin} = compile:forms([MF,EF,FF]).
{ok,z,<<70,79,82,49,0,0,1,164,66,69,65,77,65,116,111,109,0,0,0,...>>}
% load module from binary
> code:load_binary(z, "nofile", Bin).
{module,z}
% test
> z:f().
hello_world
Alternatively you can scan your string, and then cut the resulting token list at {dot, _}
tokens apart.
Store the content of the string in a file with a module name (if not there in the code) and compile it using compile module.
Code becomes available in the VM. I am using this technique to convert a configuration file into a module. This way there not much binary copy going on during the execution.
精彩评论