Dynamic Erlang动态记录编辑
我正在Dynamic Erlang动态记录编辑,dynamic,erlang,record,Dynamic,Erlang,Record,我正在mnesia中存储一些数据,我希望能够更改大部分涉及的值 天真的 change(RecordId, Slot, NewValue) -> [Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])), NewRec = Rec#rec{Slot=NewValue}, F = fun() -> mnesia:write(NewRec) end, {atomic,
mnesia
中存储一些数据,我希望能够更改大部分涉及的值
天真的
change(RecordId, Slot, NewValue) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = Rec#rec{Slot=NewValue},
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
但是仍然有一些代码重复。有没有办法把这种模式抽象出来?是否存在允许编辑记录的既定技术?一般来说有什么想法吗?因为记录是由元组表示的,所以可以尝试使用元组操作来设置单个值
-module(rec).
-export([field_num/1, make_rec/0, set_field/3]).
-record(rec, {slot1, slot2, slot3}).
make_rec() ->
#rec{slot1=1, slot2=2, slot3=3}.
field_num(Field) ->
Fields = record_info(fields, rec),
DifField = fun (FieldName) -> Field /= FieldName end,
case length(lists:takewhile(DifField, Fields)) of
Length when Length =:= length(Fields) ->
{error, not_found};
Length ->
Length + 2
end.
set_field(Field, Value, Record) ->
setelement(field_num(Field), Record, Value).
set_字段将返回更新的记录:
Eshell V5.9.1 (abort with ^G)
1> c(rec).
{ok,rec}
2> A = rec:make_rec().
{rec,1,2,3}
3> B = rec:set_field(slot3, other_value, A).
{rec,1,2,other_value}
您还可以将
change
定义为宏(尤其是仅在模块内部使用时):
使用宏,您还可以将
\uuuuu
作为字段传递(有利于模式匹配)。使用记录实际上是元组的另一种方法是:
change(RecordId, Index, NewValue) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = setelement(Index, Rec, NewValue),
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
这也是将记录作为元组的“干净”使用,因为您正在使用
#rec.name
语法查找元组中字段的索引。这就是添加此语法的原因。请参阅中的第9.8节“记录的内部表示”。字段名仅在编译时可用,因此不能在#rec语法中为字段名使用变量。record_info()函数可能会对您尝试执行的操作有所帮助。我最终执行了类似的操作。作为对阅读该问题的人的一个提示,这里也很有用。
-define(change(RecordId, Slot, NewValue),
begin
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = Rec#rec{Slot=NewValue},
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val
end).
test(R, Id) ->
?change(Id, name, 5).
change(RecordId, Index, NewValue) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = setelement(Index, Rec, NewValue),
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
5> Val = record:change(id58, #rec.name, new_value).