Преобразование записей в проплисты (и обратно) - PullRequest
8 голосов
/ 21 сентября 2010

У меня есть веб-приложение Erlang, основанное на Mochiweb и Mnesia, которое использует и испускает JSON. Имеет смысл хранить записи в Mnesia; однако Mochiweb / Mochijson требуют данные в формате проплиста. Таким образом, я получаю большое количество шаблонного кода:

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

Прекрасно с одной маленькой записью, боль с большим количеством больших записей. Кто-нибудь может предложить способ обойти весь этот шаблонный код? Я думаю, мне нужен какой-то способ динамического осмотра полей записи; и так как записи являются конструкцией во время компиляции, я предполагаю [предполагая, что это возможно], это означает внедрение кода с помощью макроса.

Спасибо!

Ответы [ 4 ]

22 голосов
/ 21 сентября 2010

Вы должны быть в состоянии сделать что-то вроде:

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

И т. Д.

(Или как макрос (хотя по-прежнему создается функция, версия, где находится макрос? R2P (Rec, foobar) просто безобразно):

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

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

)

2 голосов
/ 21 сентября 2010

Используя record_info (fields, foobar) можно что-то делать динамически.record_info, однако, также является конструкцией времени компиляции, поэтому имя записи не может быть переменной, поэтому для каждой записи, которую вы собираетесь преобразовать, требуется одно предложение.

1 голос
/ 03 октября 2010

Звучит так, будто вы ищите exprecs:

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

Чтение из описания:

Модуль является преобразованием синтаксического анализа. позволяет вам экспортировать записи. Transform добавляет функции доступа для создание экземпляров, проверка и изменение записей, без необходимости ввести зависимости времени компиляции между модулями.

Посмотрите, поможет ли это.

0 голосов
/ 27 января 2018

Ссылка в принятом ответе для этого давно устарела.

Краткий ответ - использовать exprecs от Ульфа Вигера.

exprecs - это parse_transform в uwiger / parse_trans

Статья о том, как это работает, архивируется в веб-архиве по адресу: http://web.archive.org/web/20130729014934/http://forum.trapexit.org/viewtopic.php?p=21790

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...