Heterogene Daten verwalten


  • Mod

    Nanu, geht es jetzt doch weiter mit dem IRC-Bot oder ein neues Projekt?

    Zu Frage:
    Schreib eine Klasse die im Konstruktor so einen Datenstrom bekommt und templatisierte Funktionen nach folgendem Muster anbietet:
    get_key<T>(const string & key, T & t);

    Dann machst du z.B.

    int mode;
    ircstring.get_key("MODE", mode); // mode == 4
    string chanmodes;
    ircstring.get_key("CHANMODES", chanmodes); // chanmodes = "eIbq,k,flj,CFLMPQcgimnprstz"
    

    Und falls der key nicht vorhanden ist wird eine Exception geworfen oder false zurück gegeben oder was dir eben passt.
    Verstehe ich dich mit diesem Vorschlag richtig?

    Was mir gerade schwer fällt, ist die Entscheidung, wann ein Datensatz zu Ende ist. So wie das aussieht ist das Kriterium dafür, dass auf das vorletzte Wort kein '=' folgt. Das wäre geringfügig kompliziert zu programmieren. Oder sind da eventuell irgendwelche Trennzeichen (\0, \n?) zwischen? Das würde die Sache erheblich einfacher zu parsen machen.



  • Das Parsen ist nicht unbdeingt das Problem 😉
    Ich möchte diese Daten vom Server einlesen und danach irgendwie einen schönen Zugriff darauf haben. Wie dieser aussehen könnte, möchte ich gerne wissen 🙂



  • Wieder mal zu langsam.

    Wie man hier sehen kann, wäre CHANMODES eine Liste von 4 Typen von weiteren Listen. PREFIX ist eine Liste von Modes in runden Klammern, danach eine Liste der Symbole dazu. Alles nach Rang sortiert.

    Wie könnte ich denn solche Daten sinnvoll speichern? Jedes mal von String nach X umwandeln, halte ich nicht für sinnvoll.


  • Mod

    314159265358979 schrieb:

    Ich möchte diese Daten vom Server einlesen und danach irgendwie einen schönen Zugriff darauf haben. Wie dieser aussehen könnte, möchte ich gerne wissen 🙂

    Dann steht mein Vorschlag. Zumindest wenn du zur Compilezeit weißt, welcher Datentyp zu welchem Schlüssel gehört und welche Schlüssel du überhaupt auswerten möchtest. Falls jedoch einer von oder beide diese Aspekte dynamisch sind, dann taugt er nix.



  • Ich kenne zwar diese Liste, aber es wäre möglich, dass ein Server weitere Modi unterstützt. Deshalb würde ich gerne alles parsen und entsprechenden Zugriff anbieten.

    Achja: Ja, mein Projekt geht weiter 😉



  • Diese Werte solltest du schlicht und einfach in einer map<string,string> speichern.
    Danach wertest du die für den Bot relevanten Informationen wie PREFIX, NETWORK, CHANTYPES usw. aus und bietest das passend an (z.B. isChannelPrefix() ).



  • Dann müsste doch der Benutzer alles selbst umwandeln, oder hab ich dich jetzt falsch verstanden?



  • 314159265358979 schrieb:

    Wie man sieht, kommen hier Daten bunt gemischt an. ints, strings, listen, maps und manchmal ohne Value.

    Ich sehe nur Zeichenketten.



  • 314159265358979 schrieb:

    Dann müsste doch der Benutzer alles selbst umwandeln, oder hab ich dich jetzt falsch verstanden?

    Ja, oder du machst mehrere Funktionen. Eine die direkt auf die map zugreift und dann je eine für Standardoptionen. Alles andere ist sehr frickelig. (z.B. wenn man einen Interpreter schreibt. 😉 )



  • class Serverdaten {};
    class Serverlist : public Serverdaten { std::list<int> daten};
    class Serverint : public Serverdaten {int daten};
    
    vector<Serverdaten*> parsedString;
    

    Nur als Idee. Klar, Benennung is scheiße, blanke pointer in nem vector sind scheiße, etc etc - aber geht ja um die Idee.



  • Und wie soll dann der Zugriff geschehen?



  • Würd mal sagen, hängt davon ab was du mit den Daten machen willst. Ok, davon hängt auch ab ob diese Variante überhaupt sinnvoll is.

    virtual functioncall "doSomething", sodass die Typen selbst arbeiten, wenn sie es sinnvoll können. Kannst den vektor auch sortiert machen nach relevanz der optionen, und dann mit prüfen von typeid von vorn nach hinten durchgehen.

    Kannst sie auch mit hilfe der typen im vector sortieren - dafür halt ich dann aber bald ne klasse mit je einem (vector von einem...) datentyp langsam sinnvoller.

    Kannst auch statt dem vector eine map<string, Serverdaten*> nehmen, wenn du den daten irgendwie namen zuordnen willst.

    Also, ich hab keine Ahnung von irc und weiß deshalb nicht genau was du brauchst - deshalb sollts ja nur ne idee sein.



  • Ich habe mir gerade einen anderen Ansatz überlegt, und zwar über boost::variant. Ein Element wird als variant<int, string, ...> gespeichert, diese lege ich in einer map<name, value> ab und biete Iteratoren und evtl weitere Funktionen an. Der Benutzer kann dann einen Visitor drüberlaufen lassen und je nach Typ bestimmte Aktionen ausführen.



  • Würdest Du nicht bis zum "GenericManagerOfSomething" abstrahieren, müßtest Du auch nicht zurückcasten und Typen zur Laufzeit prüfen, befürchte ich.



  • Da hast du wohl Recht, welche Probleme gibt es denn bei meiner Lösung?



  • 314159265358979 schrieb:

    Da hast du wohl Recht, welche Probleme gibt es denn bei meiner Lösung?

    Ich sehe keine Wand, gegen die man laufen könnte, das geht so durch.
    Wird halt vielleicht ein wenig zu abstrakt für einen denkfaulen Mann wie mich.



  • Ich habe mich nun doch umentschieden. Bekannte Optionen werden in gleichnamigen Variablen gespeichert, Rest in einer map<k, v>. Die Optionen sind dabei Instanzen eines templates nullable<T>, das im Prinzip nur eine Wrapperklasse um T ist, aber eben nullptr zuweisbar ist.

    Was haltet ihr davon?



  • 314159265358979 schrieb:

    Ich habe mich nun doch umentschieden. Bekannte Optionen werden in gleichnamigen Variablen gespeichert, Rest in einer map<k, v>. Die Optionen sind dabei Instanzen eines templates nullable<T>, das im Prinzip nur eine Wrapperklasse um T ist, aber eben nullptr zuweisbar ist.
    Was haltet ihr davon?

    Das würde ich noch weiter treiben:
    Bekannte Optionen werden in gleichnamigen Variablen gespeichert, Rest wird *nicht* gespeichert einself
    Wozu was lesen und speichern, das eh nicht bekannt ist?
    Und wenn Du rausgefunden hast, was die Option bedeutet, kannste ihr auch einen guten Namen und Typ geben.



  • Was hältst du von der Sache mit dem nullable? Ist das so brauchbar?
    (gibts evtl in boost sowas?)



  • Ja, es gibt boost::optional.


Anmelden zum Antworten