Frage

Ich versuche, einige Code, den ich für die Software haben, Refactoring, die aktuellen Status von Agenten in einer Anruf-Warteschlange sammelt. Derzeit für jede der 6 oder so Ereignisse, die ich höre, überprüfe ich in einem Mnesia Tabelle, wenn ein Agent vorhanden ist, und einige Werte in der Zeile auf der Veranstaltung abhängig verändern oder neue hinzufügen, wenn der Agent nicht existiert. Zur Zeit habe ich diese Mnesia Transaktion in jedem Fall und natürlich, die für die Überprüfung der Existenz von Agenten und so weiter eine Reihe von wiederholtem Code.

Ich versuche, es zu ändern, so dass es eine Funktion wie ist change_agent / 2 , dass ich von den Ereignissen nennen, die dies für mich behandelt.

Meine Probleme sind natürlich Aufzeichnungen .... Ich finde keine Möglichkeit, sie dynamisch erstellen oder 2 von ihnen zusammen oder irgendetwas zu verschmelzen. Vorzugsweise wäre es eine Funktion sein, die ich wie nennen könnte:

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

Lösung

Ich schrieb ein, während einige Code vor, dass zwei Datensätze übergeht. Ist das nicht vollständig dynamisch, aber whith Makros Sie leicht für mehrere Datensätze verwenden könnten.

Es funktioniert wie folgt: Der Merge / 2-Funktion zwei Datensätze nimmt und wandelt sie mit den leeren Datensatz Listen zusammen als Referenz (der Satzart bei der Kompilierung definiert ist, und muß diese der „undynamische“ Teil ist.) . Diese werden dann laufen durch die generische Funktion fusionieren / 4, die mit Listen arbeiten und nehmen Elemente von A, wenn sie definiert sind, sonst von B, wenn sie definiert sind, oder schließlich von Standard (die immer definiert ist).

Hier ist der Code (bitte Stackoverflow Arme Erlang-Syntax-Hervorhebung entschuldigen):

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

Fühlen Sie sich frei, um es in irgendeiner Weise zu verwenden, die Sie wollen.

Andere Tipps

Es ist schwierig, allgemeine Zugriffsfunktionen für Datensätze zu schreiben. Eine Abhilfe hierfür ist die ‚exprecs‘ Bibliothek, die generiert Code für Low-Level-Datensatz-Zugriffsfunktionen.

Das, was Sie tun müssen, um die folgenden Zeilen hinzufügen ein Modul:

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

Die Namenskonvention für die Zugriffsfunktionen mag seltsam aussehen, wurde aber von einem Vorschlag von Richard O'Keefe inspiriert. Es ist zumindest im Einklang, und unwahrscheinlich, dass mit dem bestehenden Funktionen kollidieren. (:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top