2008-09-15 4 views
3

Я пытаюсь реорганизовать код, который у меня есть для программного обеспечения, которое собирает текущее состояние агентов в очереди вызовов. В настоящее время для каждого из 6 или около того событий, которые я слушаю, я проверяю таблицу Mnesia, если агент существует и меняет некоторые значения в строке в зависимости от события или добавляет его как новое, если агент не существует. В настоящее время у меня есть транзакция Mnesia в каждом случае и, конечно же, это куча повторяющегося кода для проверки наличия агентов и т. Д.Слияние записей для Mnesia

Я пытаюсь изменить его так, что есть одна функция, например change_agent/2, которую я вызываю из событий, которые обрабатывают это для меня.

Мои проблемы - это, конечно, записи .... Я не нахожу никакого способа динамически создавать их или объединять 2 из них вместе или что-то еще. Предпочтительно была бы функция, которую я мог бы назвать следующим:

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

ответ

2

Я написал код некоторое время назад, что объединяет две записи Не совсем динамичен, но ти макросов вы можете легко использовать его для нескольких записей

Это работает так:.. Функция слияния/2 принимает две записи и преобразуют их в списки вместе с пустой записью для справки (тип записи определяется во время компиляции и должен быть. Это «нединамическая» часть). Затем они запускаются через общий слияние функций/4, который работает со списками и принимает элементы из A, если они определены, в противном случае из B, если они определены, или, наконец, из значения по умолчанию (которое всегда определено).

Вот код (пожалуйста, извините бедных Erlang от StackOverflow подсветка синтаксиса):

%%%---------------------------------------------------------------------------- 
%%% @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). 

Не стесняйтесь использовать его каким-либо образом.

3

Трудно написать общие функции доступа для записей. Обходным решением для этого является библиотека 'exprecs', которая будет генерировать код для низкоуровневых функций доступа к записи.

Что вам нужно сделать, это добавить следующие строки в модуля:

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

Соглашение об именах функций доступа может выглядеть странно, но был вдохновлен предложением Ричард О'Киф , Это, по крайней мере, непротиворечиво и вряд ли столкнется с существующими функциями. (:

+0

Быстрый взгляд на это может быть не совсем то, что я искал. Но интересно все же и кое-что, что я проверю позже. – 2008-09-15 16:33:59