Reading terms from a file.

Raimo Niskanen <>
Thu Nov 22 15:11:28 CET 2001


I encountered Thomas's problem below in a trace tool I am currently
writing. The way I will get around it is by using the fact that I only
need to get something identifiable for a human when scanned and parsed,
so i pass all suspicious terms written to the file through the following
function, which converts weird terms into their string representation:

%% Converts the parts of a deep term that are not parasable when printed
%% with io:format() into their string representation.
parsify([]) ->
    [];
parsify([Hd | Tl]) ->
    [parsify(Hd) | parsify(Tl)];
parsify({A, B}) ->
    {parsify(A), parsify(B)};
parsify({A, B, C}) ->
    {parsify(A), parsify(B), parsify(C)};
parsify(Tuple) when tuple(Tuple) ->
    list_to_tuple(parsify(tuple_to_list(Tuple)));
parsify(Pid) when pid(Pid) ->
    erlang:pid_to_list(Pid);
parsify(Port) when port(Port) ->
    erlang:port_to_list(Port);
parsify(Ref) when reference(Ref) -> 
    erlang:ref_to_list(Ref);
parsify(Fun) when function(Fun) ->
    erlang:fun_to_list(Fun);
parsify(Term) ->
    Term.

The name should possibly be 'scanify' :-).

The 2- and 3-tuple clauses are just optimisations.

/ Raimo Niskanen, Erlang/OTP, Ericsson UAB



Thomas Arts wrote:
> 
> The suggestion to read Erlang terms with file:consult
> is useful, but does not work consistent.
> 
> Erlang (BEAM) emulator version 5.1 [threads:0]
> 
> Eshell V5.1  (abort with ^G)
> 
> 3> {ok,D} = file:open("myterms",[write]).
> {ok,<0.34.0>}
> 4> file:write(D,io_lib:format("~w.~n",[{myproc,self()}])).
> ok
> 5> file:write(D,io_lib:format("~w.~n",[[1,2,3]])).
> ok
> 6> file:close(D).
> ok
> 7> file:consult("myterms").
> {error,{1,erl_parse,["syntax error before: ",["'<'"]]}}
> 
> The problem is that the scanner does not recognize process
> identifiers as such.
> 
> I am looking myself for a solution to write terms to file in
> the internal term format, like io:write(Device,Term), but than
> not in ascii format. I want to write several terms, though.
> 
> Erlang (BEAM) emulator version 5.1 [threads:0]
> 
> Eshell V5.1  (abort with ^G)
> 1> {ok,D} = file:open("myterms",[write]).
> {ok,<0.30.0>}
> 2> io:write(D,{myproc,self()}).
> ok
> 3> io:write(D,[1,2,3]).
> ok
> 4> file:close(D).
> ok
> 
> The problem is reading the file. The command io:read is
> not implemented as the inverse of io:write, which I think
> is pity.
> 
> 5> f(D).
> ok
> 6> {ok,D} = file:open("myterms",[read]).
> {ok,<0.36.0>}
> 7> io:read(D,"").
> {error,{1,erl_scan,scan}}
> 
> suggestions?
> 
> /Thomas
> 
> "Martin J. Logan" wrote:
> >
> > Hello,
> >     Does anyone have any suggestions on the best way to read erlang
> > terms from a file. I am using io_lib:fread and parsing the data I get.
> > This rather simple meathod has worked well for me in the past because I
> > was only doing simple things with files.  I would like to read in
> > complex erlang terms such as those found in the .app and .rel files.
> >
> > The way I do things right now is short but too simple.
> >
> > %% read/2: Reads the commands file
> > %% Arg1: The list of services.
> > %% Arg2: IoDevice - The io device process
> >
> > read([eof|Service], IoDevice) ->
> >     Service;
> > read(Service, IoDevice) ->
> >     String = io:get_line(IoDevice, ""),
> >     Line = normalize(io_lib:fread("~s ~a ~a ~d", String)),
> >     read([Line|Service], IoDevice).
> >
> > normalize({ok, Line, LeftOver}) ->
> >     ArgList = string:tokens(chop(LeftOver, "\n"), " "),
> >     list_to_tuple(lists:append(Line, [ArgList]));
> > normalize({ok, Line}) ->
> >     list_to_tuple(lists:append(chop(Line, "\n"), [[]]));
> > normalize(eof) ->
> >     eof.
> >
> > This allows me to read the static elements that I have in the beginning
> > of each line and then an abitrary number of leftover elements are put
> > into a list and added to the list of static elements. so I am left with
> > a ["string", atom, atom, digit, [any number of elements]]. This is fine
> > but if I could efficiantly grab erlang terms from the file I could
> > imrove the logic of my application without making it ugly.
> >
> >             Thanks,
> >              Martin Logan.



More information about the erlang-questions mailing list