2010-09-21 91 views
8

我有一個基於Mochiweb和Mnesia的Erlang web應用程序,它使用併發出JSON。在Mnesia存儲記錄是有意義的;但是Mochiweb/Mochijson需要proplist格式的數據。所以我最終得到了大量的樣板代碼:將記錄轉換爲proplists(並返回)

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

很好,只有一個小記錄,有很多大記錄的痛苦。任何人都可以提出一個方法來處理所有這些樣板代碼?我想我需要一些動態檢查記錄字段的方法;由於記錄是一個編譯時構造,我猜[假設這是可能的],這意味着通過宏注入代碼..

謝謝!

回答

1

這聽起來像exprecs就是你升ooking爲:

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

從描述閱讀:

該模塊是解析變換 讓您導出記錄。 變換爲 實例化,檢查和 添加訪問器函數,而不必 在模塊之間引入編譯時相關性 。

看看這是否有幫助。

+0

把DanialLuna的其他答案放在一起:列表:zip(league2:'#info - '(Rec),tl(tuple_to_list(Rec)) )。 – f3r3nc 2013-03-20 14:20:23

+0

鏈接已死,請在將來填寫完整的答案。 – drozzy 2016-11-22 17:18:45

2

使用record_info(字段,foobar)可以動態地執行某些操作。然而,record_info也是一個編譯時構造,所以記錄名稱不能是變量,所以對於每個要轉換的記錄需要一個子句。

21

你應該能夠做這樣的事情:

-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(拍攝,foobar的)實在是太醜陋):

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

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

+0

不錯,但我還是要爲每一個記錄record_to_proplist。想想正確的方法可能是編碼生成這個東西。 – Justin 2010-09-23 20:31:07

+1

您可以使用「find。-name」* rl「-exec grep - '-record('{} \; | sed's/-record(\([^,] * \) – 2010-09-24 15:25:45