Verschachteltes Scripting.Dictionary Objekt nicht unabhängig

  • Hier mein Skript

    Erwartet wird, dass in der Messagebox "fest" steht, stattdessen erscheint "flüssig". Was mache ich falsch? Wie kann ich es besser lösen? Danke für die Hilfe im Voraus.

  • Das ist der Unterschied der Variablenübergabe per "By Value" und "By Reference".

    $var2.add(1,$var1) gibt dem Element mit dem Key "1" des Dictionaries $var2 einen Verweis auf das Dictionary $var1.
    Das Dictionary $var1 wird weder kopiert noch dessen Werte übertragen - alles was nun in $var2 steht ist ein Verweis auf $var1.
    Das heißt auch alle Änderungen an $var1 bekommt man auch weiterhin durch auslesen von $var2.item(1) mit da dort ja nur auf das andere Dictionary verwiesen wird.

    Was du stattdessen brauchst ist für jedes item von $var2 ein jeweils eigenes Dictionary.
    Das heißt du musst also immer ein neues Dictionary erstellen anstatt immer wieder auf das selbe zu verweisen.

    Was mache ich falsch?

    • Variablendeklaration mit Dim macht nur in seltenen Spezialfällen Sinn. In allen anderen sollte man zwecks Eindeutigkeit und Übersichtlichkeit Global und Local verwenden.
    • Für $var3 erstellst du ein neues Dictionary. $var3 erhält damit einen Verweis auf das neu erstellte Dictionary. Danach weist du $var3 als Wert $var2.Item(1) zu was nichts weiter ist als ei n Verweis auf $var1. Damit geht der Verweis auf das neu erstellte Array damit flöten. Kurz: Du brauchst für $var3 kein neues Dictionary erstellen da es so wie du es machst eh nicht verwendet wird.
    • Der Quelltext-Spoiler für deinen Code hier im Thread zu verwenden war schon mal ein guter Anfang. Noch besser wäre der AutoIt-Spoiler mit dem der Code dann noch schöner dargestellt wird.

    Allgemeiner Tipp: Einfach mal per Google über "Call by Value" und "Call by Reference" informieren.

  • Danke schonmal für die prompte und ausführliche Antwort. Call by Value und Call by Reference sind mir von C geläufig. Ich hatte vermutet, dass es damit zusammenhängt.

    Zitat

    Das heißt du musst also immer ein neues Dictionary erstellen anstatt immer wieder auf das selbe zu verweisen.

    Ich schildere mal mein Problem etwas abstrakt. Ich habe mehrere Autos. Die Eigenschaften eines Autos lege ich in ein Dictionary. Meine gesamten Autos möchte ich nun in einem weiteren Dictionary als Fuhrpark zusammenfassen. Diesen Fuhrpark möchte ich nun an eine Funktion übergeben, die z.B. den Fuhrpark einfach nur ausgibt. Die einzelnen Autos zu übergeben macht da also wenig Sinn.
    Wie löse ich diese Aufgabe am besten?

    • Offizieller Beitrag

    Verwende doch AutoItObject. Für solche Strukturen sind Objekte einfacher im Handling. Und da es diese UDF gibt, wär es doch schön, wenn sie auch ab und an zur Anwendung kommt. ;)

    Alternativ könntest du auch mit Array & Struktur arbeiten: Symbiose: Array + Struktur
    Edit: Dazu hier mal ein kurzes Bsp. (Beachten: Da Struktur zur Anwendung kommt dürfen in den Feldbezeichnern Umlaute und ß nicht vorkommen!)

    [autoit]

    #include 'StructureList.au3'
    Global $Fuhrpark = _StrucList_Create(-1, 'c;Alias', 'c;Identnummer', 'c;Kennzeichen', 'c;Fabrikat', 'c;Modell', 'c;Kraftstoff', 'c;Oel', 'c;Lackierung', 'i;Buchungskonto', 'f;EK', 'f;Zeitwert', 'f;Abschreibebetrag')

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

    _StrucList_AddIndex($Fuhrpark, -1, 'Ford_09|VF08152788A36|HH VX-546|Ford|Mondeo|Diesel|HLW-40|schwarz-metallic|14560|23500.50|18575.20|4635.35')
    _StrucList_AddIndex($Fuhrpark, -1, 'Audi_01|XZ457822BVG27|HH ZT-827|Audi|Quattro|Diesel|HLW-30|silbergrau-metallic|14580|31400.30|27327.15|4928.20')

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

    ConsoleWrite('Anzahl Fahrzeuge im Fuhrpark: ' & _StrucList_Count($Fuhrpark) & @LF)
    ConsoleWrite('Auflistung nach Index (Alias-Name): ' & _StrucList_GetIndices($Fuhrpark, ';') & @LF)
    ConsoleWrite('Ölsorte von Ford_09: ' & _StrucList_GetValue($Fuhrpark, 'Ford_09', 'Oel') & @LF)

    [/autoit]
  • Es war viel einfacher als ich dachte. Ich muss einfach jedesmal ein neues Objekt erstellen. Hier der Code:

    [autoit]

    Dim $var1=ObjCreate("Scripting.Dictionary")
    Dim $var2=ObjCreate("Scripting.Dictionary")

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

    $var1.add("farbe","grün")
    $var1.add("eigenschaft","fest")
    $var2.add(1,$var1)

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

    ;$var1.RemoveAll alter Code

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

    $var1=ObjCreate("Scripting.Dictionary") ;neu
    $var1.add("farbe","gelb")
    $var1.add("eigenschaft","flüssig")
    $var2.add(2,$var1)

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

    Dim $var3=ObjCreate("Scripting.Dictionary")
    Dim $var3 = $var2.Item(1)
    msgbox(48,"Eigenschaft",$var3.Item("eigenschaft"));

    [/autoit]