Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting records to proplists (and back)

Tags:

erlang

I have a Erlang webapp, based on Mochiweb and Mnesia, which consumes and emits JSON. It makes sense to store records in Mnesia; however Mochiweb/Mochijson require data in proplist format. So I end up with a large amount of boilerplate code:

-record(foobar, {name, value}).

record_to_proplist(Record)->  
  [{name, Record#foobar.name},  
   {value, Record#foobar.value}].  

proplist_to_record(Props)->  
  #foobar{name=proplists:get_value("name", Props),  
          value=proplists:get_value("value", Props)}.  

Fine with a single small record, a pain with lots of large records. Can anyone suggest a way round all this boilerplate code ? I guess I need some way of inspecting a record's fields dynamically; and since records are a compile-time construct, I'm guessing [assuming it's possible] this means injecting code via a macro ..

Thanks!

like image 419
Justin Avatar asked Sep 21 '10 12:09

Justin


3 Answers

You should be able to do something like:

-record(foobar, {name, value}).
-record(foo, {other, fields, 'and', stuff}).

record_to_proplist(#foobar{} = Rec) ->
  lists:zip(record_info(fields, foobar), tl(tuple_to_list(Rec)));
record_to_proplist(#foo{} = Rec) ->
  lists:zip(record_info(fields, foo), tl(tuple_to_list(Rec))).

Etc.

(Or as a macro (still creating a function though, the version where the macro is ?R2P(Rec, foobar) is just too ugly):

-define(R2P(Record), record_to_proplist(#Record{} = Rec) ->
           lists:zip(record_info(fields, Record), tl(tuple_to_list(Rec)))).

?R2P(foobar);
?R2P(foo).

)

like image 108
Daniel Luna Avatar answered Nov 13 '22 09:11

Daniel Luna


It sounds like exprecs is what you're looking for:

http://forum.trapexit.org/viewtopic.php?p=21790

Reading from the description:

The module is a parse transform allowing you to export records. The transform adds accessor functions for instantiating, inspecting and modifying records, without having to introduce compile-time dependencies between modules.

See if this helps.

like image 21
Roberto Aloi Avatar answered Nov 13 '22 09:11

Roberto Aloi


Using record_info(fields, foobar) it is possible to do something dynamically. record_info however is also a compile time construct so the record name cannot be a variable, so you need one clause for each record you intend to convert.

like image 25
Lukas Avatar answered Nov 13 '22 09:11

Lukas