【转】Simple Dynamic Record Access
原文地址:Programming Experiments
原文作者:Brian Olsen
There is one thing I hate about Erlang, and it is records. It is not so much that the syntax is annoying (yet I am getting used to it), but you cannot use that syntax for dynamic field access; records are a compile-time feature.
So, without using Yariv’s Smerl for something like this, I opted for a simpler solution. Records are tuples after all, and you can get record information in a list. So, you can use these two facts to create a function to get the field you specify. Not anything stellar, but for dynamic record access, it works:
- find(Item, List) ->
- find_(Item, List, 1).
- find_(Item, [], _) -> not_found;
- find_(Item, [H|T], Count) ->
- case H of
- Item ->
- Count;
- _ ->
- find_(Item, T, Count+1)
- end.
- get_rec_value(Key, Rec, RecordInfo) ->
- case find(Key, RecordInfo) of
- not_found ->
- undefined;
- Num ->
- element(Num+1, Rec)
- end.
I couldn’t find something like “lists:find/2″, so I implemented my own. But the main function is “get_rec_value/3″. So you do this:
- 1> rd(person, {id, name, email}).
- 2> get_rec_value(name, #person{name="Brian"}, record_info(fields, person)).
- "Brian"
For fun, I also did setting record value.
- set_rec_value(Key, Value, Rec, RecordInfo) ->
- RecList = tuple_to_list(Rec),
- case find(Key, RecordInfo) of
- not_found ->
- Rec;
- Num ->
- List1 = lists:sublist(RecList, Num),
- List2 = lists:sublist(RecList, Num+2, length(RecList)),
- tuple_to_list(List1 ++ [Value] ++ List2)
- end.
- 3> set_rec_value(email, "c", #person{name="Brian", id="1", email="b"}, record_info(fields, person)).
I know this stuff looks really simple, but since I thought this was a bit of a nuisance, the fact that I cannot access records without hardcoding the values, something needed to be written.
Did I miss something though? I’d like to know. Please comment.
在 Comment 中, Philip Robinson 提供了解决这一问题的另一种方法。
他的方案是通过 EMP1 (Erlang Macro Processor v1) 在编译期解决这一问题。
[本文由 Sander 收集,Jackyz 对此进行了编辑(增加了原文链接和原文作者)]
jackyz: 对于我来说,好像并不觉得 Record 是一个多大的问题,呵呵。 ![]()


Write a Comment