I'd like to create a record from a list of attributes - not the actual proplist, but for example from #xmlElement
attributes. I've got a list of elements which I need to process and a list of possible attributes.
I could of course do something like:
create_record(Rec, [{attr1, Val}|As]) -> create_record(Rec#blah{attr1 = Val}, As);
create_record(Rec, [{attr2, Val}|A开发者_开发知识库s]) -> create_record(Rec#blah{attr2 = Val}, As);
...
But that's going to be a bit long and I already have the list of possible attributes (I could even use record_info(fields, blah)
. I see a lot of crazy ways to do it with accessing the actual record tuple with setelement, but maybe there's a simpler solution?
I'd probably be most tempted by:
create_record(Lst) ->
#blah{
attr1=proplists:get_value(attr1, Lst, default_attr1),
attr2=proplists:get_value(attr2, Lst, default_attr2),
...
}.
The point of transforming this thing into a record is probably to get static checking of attributes at compile time elsewhere in your code, so I don't think there's any harm in being straightforward and a little repetitive here.
If you do want to, the record_info magic is pretty straightforward, but remember record_info isn't a real function so this function can't be generic. (A macro could be.)
make_record(Lst) ->
list_to_tuple([blah|[proplists:get_value(X, Lst) || X <- record_info(fields, blah)]]).
If you really want dynamic keys at runtime, then use a dict.
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.
精彩评论