[erlang-questions] Pretty printing records from a program
Mats Cronqvist
mats.cronqvist@REDACTED
Fri Sep 29 11:25:49 CEST 2006
Joe Armstrong wrote:
> I have a record X in a program and all the .hrl files etc.
> How do I pretty print this from a program
the real problem is of course that record_info/2 is a macro, and not a real
function. IMO record_info should be generated by the compiler (just like
module_info/0).
now, if your module is debug compiled, you can use the fabled rec module
(that i just wrote :> ). then this snippet;
-define(PURTY(X),rec:pretty(?MODULE,X)).
-record(sucky,{t=aT,u,v=aV,w=aDubU,x=anX,y=aY,z}).
g() -> ?PURTY(#sucky{z=hello}).
will produce this output;
[{t,aT},{u,undefined},{v,aV},{w,aDubU},{x,anX},{y,aY},{z,hello}]
which is probably what you want.
mats
%-------------------------------------------------------------------
%%% File : rec.erl
%%% Author : Mats Cronqvist
%%% Description :
%%% pretty(Mod,Rec) -> list({FieldName,Value})
%%% Mod = atom() - module name
%%% Rec = record()
%%%
%%% Rec must declared in Mod.
%%% works by getting debug_info from the beam file. caches the record
%%% info in the process registry. checks compile times to see if cache
%%% is out-of-date.
%%%
%%% Created : 29 Sep 2006 by Mats Cronqvist <locmacr@REDACTED>
%%%-------------------------------------------------------------------
-module(rec).
-export([pretty/2]).
pretty(Mod,Rec) when is_tuple(Rec) -> pretty(Mod,tuple_to_list(Rec));
pretty(Mod,[RecName|Vals]) -> lists:zip(get_recinfo(Mod,RecName),Vals).
get_recinfo(Mod,RecName) ->
Key = {rec_info,Mod,RecName},
case get(Key) of
undefined ->
try put_recinfo(Mod,RecName),get_recinfo(Mod,RecName)
catch _:R -> exit({no_record_info,RecName,Mod,R})
end;
{Ctime,Fields} ->
case Ctime < ctime(Mod:module_info(compile)) of
true -> erase(Key),get_recinfo(Mod,RecName);
false -> Fields
end
end.
put_recinfo(Mod,RecName) ->
{_,C} = get_chunk(Mod,"Abst"),
Fs = try [_Fs] = [X||{attribute,_,record,{R,X}} <- C, R=:=RecName], _Fs
catch _:_ -> throw(no_such_record)
end,
F = fun({record_field,_,{atom,_,V},_})->V;
({record_field,_,{atom,_,V}})->V end,
put({rec_info,Mod,RecName},
{ctime(get_chunk(Mod,"CInf")), lists:map(F,Fs)}).
ctime(C) -> [X || X <- C, element(1,X)==time].
get_chunk(Mod,Chnk) ->
F = try hd(_F = code:which(Mod)), _F
catch _:_ -> throw(no_file)
end,
B = try {ok,{Mod,[{Chnk,_B}]}} = beam_lib:chunks(F,[Chnk]),_B
catch _:_ -> throw(not_debug_compiled)
end,
binary_to_term(B).
More information about the erlang-questions
mailing list