Dictionary-Object dynamisch befüllen

  • Hallo,

    ich versuche gerade ein Dictionary-Object welches ich via Assign erzeugt habe mit Inhalt zu füllen.
    Das Objekt wird zwar erzeugt (unter dem richtigen Namen "$test"), aber ich schaffe es dann nicht mehr die Methoden des Objekts aufzurufen, da ich den Variablen-Namen des Objekts nur in einer Variable vorliegen habe.
    Es müsste dann quasi so etwas (wie zum Beispiel in php) à la $$section geben - wobei man sich dann auch das assign sparen könnte, und gleich $$section = ObjectCreate(...) machen könnte.

    Hat jemand eine Idee, wie bzw. ob das überhaupt zu bewerkstelligen ist?

    Danke für Hilfe
    Trainer

    [autoit]


    $section = "test"

    [/autoit][autoit][/autoit][autoit]

    ;KLAPPT
    Assign($section, ObjCreate('Scripting.Dictionary'), 2)

    [/autoit][autoit][/autoit][autoit]

    ;KLAPPT NICHT
    $section.Add("test" = "bla")

    [/autoit][autoit][/autoit][autoit][/autoit]


    P.S. Ich habe gerade festgestellt, dass das Erzeugen mit Assign zwar Erfolg zurückliefert (1), aber falls ich versuche in irgendeiner Form lesend auf die variable Variable zuzugreifen, kommt die Fehlermeldung, dass sie nicht deklariert sei. Seltsam, oder?

    2 Mal editiert, zuletzt von ip_trainer (12. Juni 2011 um 17:54) aus folgendem Grund: Gelöst

    • Offizieller Beitrag

    ;KLAPPT NICHT $section.Add("test" = "bla")


    Wie auch, ist absolut sinnfrei.
    - du erstellst eine Variable mit dem Wert "test" (sinnlos und überflüssig, da Wert überschrieben wird)
    - dann verknüpst du diese Variable mit einem neuen Wert - dem Handle des Dict.Object
    - die Syntax für .Add ist falsch, richtig:

    [autoit]

    $oDict.Add($KEY, $VALUE)

    [/autoit]

    Assign ist übrigens eine absolute "Krücke" und sollte auch nur dann genutzt werden, wenn es gar nicht anders geht (was ich fast noch nie erlebt habe).

  • Hi BugFix,

    danke für deine Antwort.

    Stimmt, die Syntax für die Add-Methode war falsch, aber das war nur ein Flüchtigkeitsfehler beim Posten, sorry :rolleyes: ...

    Deine Erklärung verstehe ich aber leider nicht.

    Wieso ist das Erstellen von $section überflüssig? Ich hatte gedacht, dass der String der in $section steht ("test") als Variablen-Name bei Assign() verwendet wird, ganz gleich so wie wenn man bei Assign("STRING", "irgendwas") eine String als Name übergibt. Und nicht, dass Assign() dann wieder $test überschreibt. Schließlich bekommt die Funktion doch den Wert der in $test steht übergeben, und nicht die Variable selbst...?!? Oder liege ich da falsch?

    Zitat

    - dann verknüpst du diese Variable mit einem neuen Wert - dem Handle des Dict.Object

    Genau, ich wollte der damit erstellen Variable das Handle des Objekts zuweisen, das stimmt schon so. Das war doch mein Plan ;) .

    Wie auch immer, kennst du denn eine Lösung für das Problem?

    Danke und Gruß
    Trainer

    • Offizieller Beitrag

    Problem ist für mich deine etwas magere Problembeschreibung.
    Ich vermute daher mal aus deinen Fragmenten, dass du INI-Sektionen auslesen willst und das Dict.Objekt soll mit dem Namen der Sektion angesprochen werden. Ist das korrekt?
    Ich hänge dir mal meine Dictionary-UDF an, die kannst du dazu nutzen.

    Ahh, habe den Link doch noch gefunden ;)

  • Hi BugFix,

    hast du irgendwie schlechte Laune heute? :P

    Ich fand meine Beschreibung völlig ausreichend.

    Trotzdem vielen Dank für deine Hilfe und für die angehängte Datei.

    Gruß
    Trainer

  • Das Gegenstück zu Assign ist übrigens Eval.
    Deine Problembeschreibung an sich ist nicht das Problem. Die Benutzung von Assign/Eval ist aber in den meisten Fällen eine falsche Herangehensweise, es gibt dafür bessere Wege. Falls du eine Ini in ein Dictionary-Objet einlesen willst, dann solltest du dazu entweder Dictionary-Objekte verschachteln oder Section und Key als kombinierten Schlüssel im Objekt verwenden.

    Spoiler anzeigen
    [autoit]

    $oINI = ObjCreate('Scripting.Dictionary')
    $sSection = "test"
    $oINI($sSection) = ObjCreate('Scripting.Dictionary')
    $oINI($sSection).Add("key", "value")
    $oINI($sSection).Item("key2") = "value2"

    [/autoit] [autoit][/autoit] [autoit]

    $sSection2 = "section"
    $oINI.Item($sSection) = ObjCreate('Scripting.Dictionary')
    $oINI($sSection2).Add("key2") = "value2"
    $oINI.Item($sSection2).Item("key2") = "value2"

    [/autoit] [autoit][/autoit] [autoit]

    $sSection2 = "section"
    $oINI.Add($sSection, ObjCreate('Scripting.Dictionary'))

    [/autoit]

    PS: Das sind alles gültige Zugriffsarten für das Dictionary-Objekt

    Einmal editiert, zuletzt von progandy (12. Juni 2011 um 17:03)

  • Die "magere Beschreibung" bezieht sich nicht auf das spezielle Problem sondern darauf das du nicht schreibst was am Ende damit gemacht werden soll und wozu es dienen soll.
    Ich kann mir nicht vorstellen das du an Assign nicht vorbei kommst.
    Wenn du wirklich das mit den Ini-Dateien und den Dictionarys vorhast dann verschachtel doch die Dictionarys.
    Also ein Dictionary welches als Elemente den Sektionsnamen und als Wert jeweils ein weiteres Dictionary mit den Sektionsinhalt.
    Bsp:

    Spoiler anzeigen
    [autoit]

    Global $s_IniFile = "Test.ini"
    Global $dct_Sections = ObjCreate('Scripting.Dictionary')

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; Ini-Datei in $dct_Sections einlesen:
    Global $a_Sections = IniReadSectionNames($s_IniFile)
    For $i = 1 To $a_Sections[0]
    $dct_Temp = ObjCreate('Scripting.Dictionary')
    $a_Section = IniReadSection($s_IniFile, $a_Sections[$i])
    For $x = 1 To $a_Section[0][0]
    $dct_Temp($a_Section[$x][0]) = $a_Section[$x][1]
    Next
    $dct_Sections.add($a_Sections[$i],$dct_Temp)
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; $dct_Sections ausgeben:
    For $Section In $dct_Sections.Keys
    ConsoleWrite("---------- " & $Section & " -------------" & @CRLF)
    For $Key In $dct_Sections($Section).Keys
    ConsoleWrite(@TAB & $Key & " = " & $dct_Sections($Section).Item($Key) & @CRLF)
    Next
    Next

    [/autoit]

    Edit: Na das war wohl etwas zu spät

  • @progandy, AspirinJunkie,

    habt vielen Dank für euere Tips! Ihr habt übrigens ALLE Recht, genau das mit wollte ich machen (ini einlesen und in Dicionary überführen) :P.

    Und um ganz ehrlich zu sein, wollte ich nicht so direkt rausposaunen was ich machen will, weil ich das fertige Skript nachher posten wollte (so als Überraschung irgendwie, k.A. - war vielleicht doof. Zumal ja allem Anschein nach das Problem, dass es in Autoit dafür keine native Funktion gibt schon mehrfach erkannt und gelöst worden ist ^^ ).

    Also nochmal vielen Dank. Trotzdem würde mich noch interessieren, ob es denn eine Entsprechung / Workaround zu $$variablen gibt, mal ganz unanhäng von o.g. Problem. Ich hätte das schon öfters mal gebrauchen können.

    Gruß
    Trainer

  • Wie schon gesagt, es gibt Eval. Du musst Objekte aber immer zuerst in eine temporäre Variable ablegen. (Arrays ebenfalls)

    [autoit]

    Assign("a", ObjCreate("Scripting.Dictionary"))

    [/autoit][autoit][/autoit][autoit]

    $o = Eval("a")
    $o.Add("test", "1")

    [/autoit]
  • :) das hatte ich schon gelesen, aber das ist irgendwie nicht ganz das was ich meine:

    Ein Beispiel in php:

    PHP
    $test = "hallo";
    $$test = "Freunde";
    
    
    //Gibt "Freunde" aus
    echo $hallo;
  • Die Funktion tut genau das, was du willst. Hast du dir schon mal das Beispiel angesehen?
    Zuweisen = Assign
    Auslesen = Eval

  • Ok, ich denke du hast schon Recht. In php isses wohl einfach ein wenig eingängiger/ direkter.

    Ich schließe den Thread jetzt mal, das Thema ist wohl hinreichend behandelt worden, oder?

    Vielen Dank nochmal an alle.

    Gruß
    Trainer