首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mnesia合并记录

Mnesia合并记录
EN

Stack Overflow用户
提问于 2008-09-15 11:54:16
回答 2查看 913关注 0票数 3

我正在尝试重构一些代码,用于收集呼叫队列中代理的当前状态的软件。当前,对于侦听的6个左右事件中的每个事件,如果存在代理,我将签入Mnesia表,并根据事件更改行中的一些值,如果不存在代理,则将其作为新值添加。目前,我在每个事件中都有这个Mnesia事务,当然,这是一堆用于检查代理是否存在的重复代码,等等。

我正在尝试更改它,以便从为我处理此事件的事件中调用一个类似于change /2的函数。

我的问题当然是记录..。我没有办法动态地创建它们,或者将其中的两个合并在一起或其他任何东西。最好有一个我可以调用的函数:

代码语言:javascript
运行
复制
change_agent("001", #agent(id = "001", name = "Steve")).
change_agent("001", #agent(id = "001", paused = 0, talking_to = "None")).
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2008-09-15 13:32:15

不久前,我写了一些合并两条记录的代码。并不完全是动态的,但是使用宏您可以很容易地将它用于几个记录。

它的工作方式如下: merge/2函数接受两个记录,并将它们与空记录一起转换为列表以供参考(记录类型是在编译时定义的,而且必须是。这是“非动态”部分)。然后,它们通过泛型函数merge/4运行,它与列表一起工作,如果定义了元素,则从A获取元素,如果定义了元素,则从B获取元素,或者从默认值(总是定义元素)中获取元素。

下面是代码(请原谅StackOverflow糟糕的Erlang语法突出显示):

代码语言:javascript
运行
复制
%%%----------------------------------------------------------------------------
%%% @spec merge(RecordA, RecordB) -> #my_record{}
%%%     RecordA = #my_record{}
%%%     RecordB = #my_record{}
%%%
%%% @doc Merges two #my_record{} instances. The first takes precedence.
%%% @end
%%%----------------------------------------------------------------------------
merge(RecordA, RecordB) when is_record(RecordA, my_record),
                             is_record(RecordB, my_record) ->
    list_to_tuple(
        lists:append([my_record],
                     merge(tl(tuple_to_list(RecordA)),
                           tl(tuple_to_list(RecordB)),
                           tl(tuple_to_list(#my_record{})),
                           []))).

%%%----------------------------------------------------------------------------
%%% @spec merge(A, B, Default, []) -> [term()]
%%%     A = [term()]
%%%     B = [term()]
%%%     Default = [term()]
%%%
%%% @doc Merges the lists `A' and `B' into to a new list taking
%%% default values from `Default'.
%%%
%%% Each element of `A' and `B' are compared against the elements in
%%% `Default'. If they match the default, the default is used. If one
%%% of them differs from the other and the default value, that element is
%%% chosen. If both differs, the element from `A' is chosen.
%%% @end
%%%----------------------------------------------------------------------------
merge([D|ATail], [D|BTail], [D|DTail], To) ->
    merge(ATail, BTail, DTail, [D|To]); % If default, take from D
merge([D|ATail], [B|BTail], [D|DTail], To) ->
    merge(ATail, BTail, DTail, [B|To]); % If only A default, take from B
merge([A|ATail], [_|BTail], [_|DTail], To) ->
    merge(ATail, BTail, DTail, [A|To]); % Otherwise take from A
merge([],        [],        [],        To) ->
    lists:reverse(To).

你可以随意使用它。

票数 2
EN

Stack Overflow用户

发布于 2008-09-15 12:55:56

很难为记录编写通用访问函数。解决这一问题的一个方法是“箴言”库,它将为低级记录访问函数生成代码。

您需要做的是将以下行添加到模块中:

代码语言:javascript
运行
复制
-compile({parse_transform, exprecs}).
-export_records([...]).  % name the records that you want to 'export'

访问函数的命名约定可能看起来很奇怪,但灵感来自理查德·奥基夫( Richard‘’Keefe)的提议。它至少是一致的,不太可能与现有的职能发生冲突。(:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档