Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang 合并记忆记录_Erlang_Mnesia - Fatal编程技术网

Erlang 合并记忆记录

Erlang 合并记忆记录,erlang,mnesia,Erlang,Mnesia,我正在尝试重构一些代码,用于收集呼叫队列中代理的当前状态的软件。目前,对于我侦听的6个左右的事件中的每一个,我都会检查Mnesia表中是否存在代理,并根据事件更改行中的某些值,如果代理不存在,则将其添加为新值。目前,我在每个事件中都有这个Mnesia事务,当然,这是一堆重复的代码,用于检查代理的存在等等 我正在尝试更改它,以便有一个类似change\u agent/2的函数,我从事件中调用它来为我处理这个问题 我的问题当然是记录。。。。我找不到动态创建它们或将其中两个合并在一起的方法。最好有一个

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

我正在尝试更改它,以便有一个类似change\u agent/2的函数,我从事件中调用它来为我处理这个问题

我的问题当然是记录。。。。我找不到动态创建它们或将其中两个合并在一起的方法。最好有一个我可以调用的函数,比如:

change_agent("001", #agent(id = "001", name = "Steve")).
change_agent("001", #agent(id = "001", paused = 0, talking_to = "None")).

很难为记录编写通用访问函数。 这方面的一个解决办法是图书馆 将为低级记录访问功能生成代码

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

-compile({parse_transform, exprecs}).
-export_records([...]).  % name the records that you want to 'export'

访问函数的命名约定可能看起来很奇怪,但其灵感来自Richard O'Keefe的建议。它至少是一致的,而且不太可能与现有的功能发生冲突。(:

我不久前写了一些代码,合并了两条记录。它不完全是动态的,但通过宏可以轻松地将其用于多条记录

其工作原理如下:merge/2函数获取两条记录,并将它们与空记录一起转换为列表以供参考(记录类型在编译时定义,并且必须是。这是“非动态”部分)。然后通过通用函数merge/4运行这些函数,该函数使用列表并从A(如果已定义)获取元素,否则从B(如果已定义)获取元素,最后从默认值(始终已定义)获取元素

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


您可以随意使用它。

快速查看一下,这可能不是我想要的。但是很有趣,我稍后会查看。
%%%----------------------------------------------------------------------------
%%% @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).