Alex: Konfigurationsparser

Hallo,

ich möchte gern einen relativ simplen Konfigurationsparser bauen. Als Ergebnis möchte ich gerne ein Objekt haben, das ich mit dem Namen einer Konfigurationsoption befragen kann und welches darauf mit dem entsprechenden Wert dieser Option antwortet. Genau hier bräuchte ich etwas Hilfe:

Die Werte der einzelnen Optionen können beispielsweise Integers, Floats und Strings sein. Nehmen wir an, der Parser hätte beim Lesen der Konfigdatei bereits alles ausgeknobelt und wüßte, welche Option welchen Datentyp hat. Nehmen wir außerdem an, daß bestimmte Optionen immer einen festen Typ haben, d.h. optA ist immer ein Float, optB immer ein Integer, ... Wenn ich nicht gerade eine dynamisch typisierte Sprache wie z.B. PHP verwende stellt sich nun folgende Frage:

Wie gestalte ich am besten eine Methode (nennen wir sie mal getValue), um auf diese Werte zuzugreifen? Sie müßte ja quasi einen variablen Rückgabetyp haben.

Mir fallen dazu drei Möglichkeiten ein:

(1) Der Rückgabewert ist sowas wie Microsofts VARIANTs (aus COM), d.h. Typ und Wert werden gemeinsam gespeichert und man muß _nach_ Erhalt dieses Wertes prüfen, was man eigentlich bekommen hat.

(2) Der Aufrufer _weiß_, was er haben will, bekommt von getValue nur sowas wie einen Null-Pointer in C und muß dann selber auf den entsprechenden Datentyp casten.

(3) Ähnlich wie (2), nur daß es für jeden Datentyp eine eigene Version von getValue gibt. Die Abfrage von optB könnte dann z.B. über eine Methode mit dem Prototyp int getIntValue(string optName) passieren.

Version (2) scheidet eigentlich schon aus, weil (3) das Gleiche in meinen Augen etwas "sauberer" löst. Version (1) fand ich immer recht hakelig in der Verwendung ...

Letztlich laufen diese drei Versionen aber immer auf das gleiche Prinzip hinaus. Gibt es denn für statisch typisierte Sprachen wie C oder Java noch andere, vielleicht _bessere_ Ansätze?

Viele Grüße

Alex

  1. Hi!

    Wie gestalte ich am besten eine Methode (nennen wir sie mal getValue), um auf diese Werte zuzugreifen? Sie müßte ja quasi einen variablen Rückgabetyp haben.

    Dann kommt im einfachsten Fall nur object als der Basistyp aller Typen in Frage plus Typecasts. Gleichnamige Methoden müssen sich (üblicherweise) in Gegebenheiten unterscheiden, die beim Anwenden eindeutig sind. Bei unterschiedlichen Rückgabetypen aber stets gleichem Rest ist das schwer möglich.

    (1) Der Rückgabewert ist sowas wie Microsofts VARIANTs (aus COM), d.h. Typ und Wert werden gemeinsam gespeichert und man muß _nach_ Erhalt dieses Wertes prüfen, was man eigentlich bekommen hat.

    Umständlich. Im Allgemeinen weiß man ja, was man für einen Typ erwartet, weil die nachfolgende Verarbeitung genau darauf abgestimmt ist. Im Grunde ist diese Variante auch nichts großartig anderes als einen Basistyp zurückzugeben und zu casten.

    (2) Der Aufrufer _weiß_, was er haben will, bekommt von getValue nur sowas wie einen Null-Pointer in C und muß dann selber auf den entsprechenden Datentyp casten.

    Null-Pointer? Du meinst einen Basistyp, unter C vielleicht einen untypisierten Pointer, weil es da keinen gemeinsamen Basistypen gibt, soweit ich das weiß. Ich kenne nur C#.

    (3) Ähnlich wie (2), nur daß es für jeden Datentyp eine eigene Version von getValue gibt. Die Abfrage von optB könnte dann z.B. über eine Methode mit dem Prototyp int getIntValue(string optName) passieren.

    Das ist der übliche herkömmliche Weg, so wie ich ihn kenne.

    Gibt es denn für statisch typisierte Sprachen wie C oder Java noch andere, vielleicht _bessere_ Ansätze?

    Wenn Generics zur Verfügung stehen, kann man zumindest die vielen Methoden in eine zusammenfassen, der man den gewünschten Typ mitgibt. Die dahinter steckende Arbeit bleibt die gleiche, nur dass man nicht mehr viele spezielle Methoden hat sondern nur noch eine, die viele Fälle bearbeiten muss (falls sie nicht weiterdelegiert).

    getValue<T>(optionName)

    Lo!

    1. Hallo dedlfix,

      danke für Deine Antwort.

      (2) Der Aufrufer _weiß_, was er haben will, bekommt von getValue nur sowas wie einen Null-Pointer in C und muß dann selber auf den entsprechenden Datentyp casten.

      Null-Pointer?

      Argh, natürlich nicht. Ich meinte einen Void-Pointer. Wo hab ich nur meinen Kopf ...

      Gibt es denn für statisch typisierte Sprachen wie C oder Java noch andere, vielleicht _bessere_ Ansätze?

      Wenn Generics zur Verfügung stehen, kann man zumindest die vielen Methoden in eine zusammenfassen, der man den gewünschten Typ mitgibt. Die dahinter steckende Arbeit bleibt die gleiche, nur dass man nicht mehr viele spezielle Methoden hat sondern nur noch eine, die viele Fälle bearbeiten muss (falls sie nicht weiterdelegiert).

      Ja, das stimmt. Hatte ich nicht mit aufgeführt, weil es ja auch nur eine Art Verpackung des vorher skizzierten Prinzips ist und zudem noch recht sprachspezifisch.

      Bin mal gespannt, ob sich vielleicht in anderen Antworten noch ein paar Alternativen zu der Methode finden, die ich unter (3) beschrieben habe ...

      Viele Grüße

      Alex

      1. Hi!

        Null-Pointer?
        Argh, natürlich nicht. Ich meinte einen Void-Pointer. Wo hab ich nur meinen Kopf ...

        Wirklich void? Der soll doch nicht ungültig sondern nur typenlos sein.

        Ja, das stimmt. [Generics] Hatte ich nicht mit aufgeführt, weil es ja auch nur eine Art Verpackung des vorher skizzierten Prinzips ist und zudem noch recht sprachspezifisch.

        Alle Typbehandlung ist mehr oder weniger sprachspezifisch. Es ist zwar schön, wenn man alle Möglichkeiten kennt, aber nützen können einem in erster Linie nur die, die man auch verwenden kann.

        Lo!

        1. Hallo,

          Null-Pointer?
          Argh, natürlich nicht. Ich meinte einen Void-Pointer. Wo hab ich nur meinen Kopf ...
          Wirklich void? Der soll doch nicht ungültig sondern nur typenlos sein.

          ja, und genau das ist in C/C++ ein void*. Ein Zeiger auf nichts im Sinne von "nichts Konkretes". Du hast Recht, wenn man es nach der Wortbedeutung interpretiert, ist das eine irreführende Nomenklatur. Ist aber so.

          Ciao,
           Martin

          --
          Ordnung ist, wenn man etwas findet, was man gar nicht sucht.