• Ja... wenn ich den Gültigkeitsbereich explizit festlegen will... doch wenn ich es nicht will, kommt Dim ins Spiel... denn gibt es die Variable bereits im globalen Scope, wird dieser verwendet, anderfalls wird eine lokale Variable erzeugt - und somit hat Dim sehr wohl eine Lebensberechtigung!

    Ich verstehe schon, was Du meinst. Falls ich mich recht erinnere ist es auch nicht das erste Mal, dass Du auf diesen Umstand hinweist. Was hältst Du davon, dies als (Ergänzungs-)Vorschlag im aktuellen AutoIt-Hilfethread zur Diskussion zu stellen. Dort ist das Thema meiner Meinung nach besser aufgehoben, als hier im JSON-Thread.

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Wenn du mir einen Link zu diesem Thread gibst, werde ich es machen...

    Ich würde es hier posten :

    Fehler-in-der-deutschen-hilfe-bitte-hier-melden-hilfedatei-3-3-14-5-2021-07-31

    Die aktuelle Empfehlung "Global/Local statt Dim" zu verwenden ist zwar kein Fehler im eigentlichen Sinn.

    Es wurde in dem Thread (und seinen Vorgängern) aber auch über ggf. sinnvolle Ergänzungen diskutiert.

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Musashi Ich habe die deutsche Hilfe jetzt nicht gecheckt. Aber das ist mit Sicherheit da drin. Das sind ja die Grundlagen.

    Warum deshalb Dim eine gute Wahl sein sollte erschließt sich mir überhaupt nicht.. Das ist doch Käse.

    Grüße autoiter

  • Musashi Ich habe die deutsche Hilfe jetzt nicht gecheckt. Aber das ist mit Sicherheit da drin. Das sind ja die Grundlagen.

    In der aktuellen Hilfe, siehe https://autoit.de/onlinehilfe/online/html/keywords/Dim.htm , findet man zu Global/Local/Dim folgenden Hinweis :

    Spoiler anzeigen

    Der Unterschied zwischen Dim, Local und Global ist der Gültigkeitsbereich, für den die Variablen deklariert werden:


    Dim = Wenn der Variablename nicht schon mit globalem Gültigleitsbereich existiert, hat die definierte Variable einen lokalen Gültigkeitsbereich (falls die Variable schon global existiert, so wird die globale Variable verwendet.)

    Global = Erzwingt globale Gültigkeit der Variablen

    Local = Erzwingt lokale Gültigkeit der Variablen, bzw. innerhalb der Funktion

    Man sollte Local oder Global anstelle von Dim verwenden, um explizit den Gültigkeitsbereich für die Variable / Konstante / Array festzulegen.

    Dass Dim unter gewissen Umständen sinnvoll sein könnte, wird dort nicht erwähnt !

    Warum deshalb Dim eine gute Wahl sein sollte erschließt sich mir überhaupt nicht.. Das ist doch Käse.

    Bitnugger hat ein Beispiel gepostet (siehe #80 ) in dem er zeigt, dass Dim möglicherweise doch von Nutzen sein kann. Genau diese Frage soll ja z.B. in dem von mir vorgeschlagenen Thread (siehe #83) diskutiert werden.

    AspirinJunkie : Sorry, dass wir Deinen JSON-Thread hier etwas zumüllen. Ggf. können die letzten Beiträge zu Dim später verschoben werden.

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Musashi Danke für den Link. Aus meiner Sicht zeigt Bitnugger da nicht, dass es sinnvoll sein kann, sondern wie es funktioniert. Wenn aber jemand deinen Code nachher verstehen soll, dann benutzt man doch besser den längeren Weg If Not isdeclared("x") Then Local.. . Dann versteht das auch jeder andere. Wenn man schon unnachvollziehbar schreibt, dann kann man die Deklaration in der Funktion doch ganz weglassen. Da passiert das gleiche.

    Grüße autoiter

  • mko

    Jo danke - ich werde mich wohl zwingen MustDeclareVars mehr zu verwenden.

    Zur Diskussion ob die Deklaration innerhalb oder außerhalb der Schleife besser aufgehoben wäre würde ich gern etwas ausholen, da ein "ist schlechter Stil" in der Regel als Begründung unbefriedigend ist:
    Local/Global/Dim vor dem Variablennamen bedeuten immer eine [Neu]Deklaration einer Variable.
    Das heißt im Speicher wird Platz für eine neue Variable reserviert und dieser Speicher entsprechend vorbereitet.
    Da AutoIt-Variablen intern etwas aufwendiger aufgebaut sind, ist diese Deklaration also in AutoIt besonders aufwendig.

    Das reine Zuweisen eines Wertes ("Definition") hingegen ist simpler, da einfach nur der Wert an die bereits vorhandene Speicherstelle geschrieben wird.

    Sprich: Es ist effizienter eine Variable nur einmal zu deklarieren und danach nur noch ihren Wert entsprechend zu ändern.
    Und um es ganz anschaulich zu machen hier ein kurzes Beispiel um den Effekt zu sehen:

    Zu der Dim/Global/Local-Diskussion:
    Stimmt schon alles.
    Das Hauptargument gegen Dim ist eben, dass man beim Codeteil nicht weiß ob es nun eine globale oder eine lokale Variable werden soll.
    Es kommt schlicht darauf an in welchem Kontext die Funktion ausgeführt wird.
    Das führt natürlich dazu, dass eine Funktion 100x funktioniert weil die Variable local wird und beim 101. Skript geht auf einmal alles schief weil in dem Skript auf einmal jemand eine globale Variable mit selben Namen definiert hat.
    Dim ist daher tatsächlich zu vermeiden wenn man nicht einen ganz bewussten Anwendungsfall hierfür hat.

    Genau so ein arg konstruiertes Beispiel wo der Einsatz von Dim Sinn macht hätte ich sogar zufällig:
    Wenn man eine ByRef-Variable in seiner Funktion zur Rückgabe von Werten als Array verwenden möchte.

    Hier kann es jedoch sein, dass der User entweder ein Array oder eben doch einen Skalar übergibt.

    Bei einem Skalar kann man daraus jedoch kein Array mehr basteln, deswegen muss der User eine Array-Variable übergeben.
    Mit Dim hingegen kann man dies umgehen:

    Code
    #include <Array.au3>
    
    Global $x
    Test($x)
    
    _ArrayDisplay($x)
    
    Func Test(ByRef $aArray)
        Dim $aArray[2] = ["Ein", "Test"]
    EndFunc
  • Es freut mich, dass mein "schlechter Programmierstil" so angeregt Diskutiert wurde. Immerhin hat es schliesslich ein klein wenig zur Verbesserung der UDF beigetragen ;) - und MustDeclareVars zu verwenden ist auch nicht so verkehrt ;)

  • Die Function __JSON_FormatString (Maskieren des Jsonstrings)

    könnte noch um das {Tab} Zeichen Chr(9) erweitert werden:

    $s_String = StringReplace($s_String, Chr(9), "\t", 0, 1)

  • Das Escapen von Tabulatoren hatte ich bewusst rausgelassen.
    Hintergrund ist, dass JSON den Anspruch hat menschenlesbar zu sein und escapete Tabulatoren da stören könnten.
    Aber du hast Recht - auch wenn es in der Praxis keine wirklichen Probleme macht, so sind Tabulatoren in JSON-Strings lt. Standard nicht erlaubt.

    Ich habe dies ergänzt.

    Dies nutze ich gleich auch um eine überarbeitete Variante der JSON-UDF hochzustellen, welche schon lange bei mir schlummert.

    Die größte Änderung ist, dass Objekte nun nicht mehr in (externe) Scripting.Dictionary-Objekte geparst werden sondern in AutoIt-Maps.

    Das bedeutet jedoch, dass alte Skripte, welche die UDF verwenden einer Anpassung bedürfen.
    Ältere Versionen von AutoIt scheiden gleich ganz aus.

    Ich habe daher bisher gezögert diese Version hochzustellen.

  • Hi AspirinJunkie ,

    ich habe mal eine zusätzliche Funktion erstellt, die es erlaubt anstelle von einem Index für ein Array, eine Bedingung zur Identifizierung des Index zu übergeben.
    Solange ein Array nur Werte enthält, ist das uninteressant. Habe ich aber Schlüssel-Wert Auflistungen, kann ich anhand des Wertes eines Schlüssels den Eintrag im Array lokalisieren.

    Bisher würde ich mir das Array ausgeben lassen und dann das Array weiter abfragen.

    Ich fand es aber reizvoll die Bedingungen der Auswahl anstelle des Index zu übergeben und direkt auf den Inhalt zuzugreifen. Das funktioniert in der Form auch verschachtelt.

    Hier mal mein Bsp. JSON

    Hier meine Funktion

  • Du hast quasi die JSON_Get-Funktion um eine wertebasierte Filterfunktion erweitert?
    Cool - ich muss mir das erstmal genauer anschauen, da es auf den ersten Blick so aussieht, als hättest du es geschafft die Funktionalität simpler und effektiver umzusetzen als bei meiner JSON_Get.

    Ich würde diesen Denkansatz spontan gerne verwenden um die JSON_Get-Syntax, nach deiner Zustimmung, um eine Filterfähigkeit zu erweitern, anstatt eine Extra-Funktion mit hinzuzufügen (Credits natürlich entsprechend anpassen).
    Außerdem habe ich ja den Schritt Richtung Maps weg von Dictionaries genommen.
    Alleine deshalb müsste ich es ja noch anpassen.

    Heute bin ich aber da nicht ganz aufnahmefähig, da der Spieleabend mit der Großen Vorrang hat ;)

    Aber danke schonmal - sowohl für die Grundidee als Erweiterungsansatz als auch für die konkrete Umsetzung. :thumbup:

    Im Grunde überlege ich auch die Funktion namentlich von JSON zu trennen, da die Funktion JSON_Get als auch deine JSON_Query() eigentlich gar nicht auf JSON beschränkt ist sondern allgemein verschachtelte AutoIt-Strukturen behandeln kann.

  • als hättest du es geschafft die Funktionalität simpler und effektiver umzusetzen als bei meiner JSON_Get.

    Danke für die Blumen - aber nicht wirklich. ;)

    _JSON_Query ist quasi _JSON_Get mit der Möglichkeit statt Indizes Bedingungen für die Arrays zu übergeben.

    Im Prinzip mache ich nur Folgendes:

    • sind Bedingungen in den Array-Pattern enthalten?

    wenn nein: Return _JSON_Get mit dem übergebenen Pattern (Man braucht also _JSON_Get nicht mehr aufrufen, macht _JSON_Query sowieso)

    wenn ja:

    • erste Arrayposition mit Bedingung im Pattern suchen

    • den Teil des Patterns davor (repräsentiert das Array) mit _JSON_Get abfragen - liefert das Array

    • durch dieses Array iterieren und vergleichen ob der Schlüssel an der Indexposition den Wert aus der Bedingung liefert - wenn ja: das ist der gesuchte Index

    • im Ausgangspattern die Bedingung mit dem gefundenen Index ersetzen

    • das Ganze wiederholen bis keine Bedingung mehr gefunden wird

    Jetzt enthält das Pattern statt der Bedingungen die zugehörigen Indizes.

    Mit diesem Pattern rufe ich jetzt _JSON_Get auf

    Ich würde diesen Denkansatz spontan gerne verwenden um die JSON_Get-Syntax, nach deiner Zustimmung, um eine Filterfähigkeit zu erweitern, anstatt eine Extra-Funktion mit hinzuzufügen (Credits natürlich entsprechend anpassen).

    Kannst Du gerne tun.

    Im Grunde überlege ich auch die Funktion namentlich von JSON zu trennen, da die Funktion JSON_Get als auch deine JSON_Query() eigentlich gar nicht auf JSON beschränkt ist sondern allgemein verschachtelte AutoIt-Strukturen behandeln kann.

    Da ist was dran. Ich hatte auch schon überlegt, wie ich das SQL-ähnlich gestalten kann, um auch komplex Filtern zu können, z.B. aus einer JSON / einer Map / einem Array ... mit Personendaten (sagen wir mal: "Name", "Vorname", "Geschlecht", "Alter", "PLZ", "Ort", "Strasse", "Nr", "Beruf", "Jahreseinkommen") wollen wir alle Männer unter 40 mit einem jährl. Einkommen von XYZ im PLZ-Gebiet 10... abfragen. Wir können also zwischen 0 und n Ergebnisse bekommen - das Ergebnis dann wiederum in einer brauchbaren Form ausgeben (enumeriertes Array, Map, Dictionary...).

    Die Syntax kann man tatsächlich extrem zusammenstreichen:

    select - braucht man nicht, ist das einzige Ziel beim Filtern

    fields - ja, das muss sein

    from table - braucht man auch nicht, ist immer rückbezüglich auf die Position im Pattern

    where - das Schlüsselwort ist auch unnütz, na klar kommen nun die Bedingungen

    conditions - genau, das brauchen wir

    Bleibt nur die Gestaltung der Operatoren, da liebäugele ich mit den C++/Phyton Operatoren: and = &&, or = Doppelte-Pipe (wird vom Editor als Smiley gezeigt), not = !. (Symbole sind m.M.n. einfacher/eindeutiger zu Parsen, als Worte). Zusätzlich natürlich: < = > und auch contains - wobei ich dafür wiederum auch ein Symbol verwenden würde, vielleicht: ?

    Damit sollten eigentlich wesentliche Filteroperationen möglich sein. Es wird sicher nur etwas aufwändig, die Auswertelogik zu gestalten (Berücksichtigung aller Klammerausdrücke, Rangfolge der Operatoren). Aber es hat ja auch keiner behauptet, dass sowas ein Spaziergang sei. :rofl:

  • Damit sollten eigentlich wesentliche Filteroperationen möglich sein. Es wird sicher nur etwas aufwändig, die Auswertelogik zu gestalten (Berücksichtigung aller Klammerausdrücke, Rangfolge der Operatoren). Aber es hat ja auch keiner behauptet, dass sowas ein Spaziergang sei.

    Evtl. kannst du dir die Funktion _CssOnDom() von >>Hier<< anschauen.
    Dort wurde eine solche Filterung von Elementen bereits umgesetzt.
    Allerdings auf die spezielle Struktur dort (jedes Element ist ein 3-Element-Array) hin aufgebaut.
    Aber die verschachtelte Abfragelogik auf Basis bereits verbreiteter CSS-Syntax könnte man auf den Fall hier anpassen.

  • Nun auch mal meine Butter dazu gebe. :rofl:
    Habe mich immer gefragt was dieses "JSon" ist und nun Wiki befragt. Sieht sehr inetrresant aus, auch wenn ich davon nur 75% vielleicht verstanden habe. :rofl:

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Es ist eine neue coole Funktion hinzugekommen.
    Bisher konnte man mit _JSON_Get() sich Werte einfach selbst aus stark verschachtelten AutoIt-Strukturen (wie sie z.B. von _JSON_Parse() erzeugt werden) auslesen.
    Verändern oder Löschen ging bisher aber nur manuell.
    Nun steht hierfür die Funktion _JSON_addChangeDelete() zur Verfügung.

    Man kann mit ihr Werte ändern oder löschen aber was im Grunde noch cooler ist: Man kann mit dieser Funktion ziemlich simpel komplexe Strukturen überhaupt erst erzeugen.

    Am besten sieht man das wahrscheinlich am Beispiel:

  • Hi.

    Vielleicht kann mir hier jemand helfen. Ich versuche mein Open Source Programm Media-Buddy auch unter Linux ans Laufen zu bekommen, mit Hilfe von Wine. Ja, AutoIt ist nur für Windows, aber im allgemeinen laufen die kompilierten Skripte problemlos unter Wine.

    Eigentlich würde das auch hier funktionieren, aber es kommt beim Start immer eine Fehlermeldung "xxx.json" is not valid" und mein Programm beendet sich danach. Da ich diese Fehlermeldung nirgends selbst erzeuge, müsste sie eigentlich von der UDF her kommen. Unter Windows funktioniert alles. Die betreffende .json Datei selbst ist absolut in Ordnung. Die Fehlermeldung ist also eigentlich falsch. Was könnte da der Grund sein, denn .json sollte doch eigentlich Plattform- unabhängig sein? Wenn eine bestimmte Windows DLL dafür in der UDF verwendet wird, welche genau? Dann würde ich diese DLL mal in Wine zusätzlich installieren und schauen, ob es dann funktioniert.

    Ich habe noch nicht die neue 2023er Version der UDF in Gebrauch, werde ich gleich downloaden und testen.

    Ich bekomme in letzter Zeit immer mehr Anfragen, ob es Media-Buddy nicht auch als Linux Version geben könnte. Deswegen habe ich mir Linux Mint als Dual Boot zusätzlich auf meinem Rechner installiert. Media-Buddy hat sich über ca. 10 Jahre hinweg entwickelt und besteht aus ca. 30.000 Zeilen Code (ohne die zusätzlichen UDF, die ich verwende), was es praktisch unmöglich macht, es in eine andere Sprache (z.B. Free Basic) zu portieren. Wenn ich also eine Linux Version verfügbar machen will, dann nur über Wine.

    Außerdem gibt es ja Gerüchte, das Windows zukünftig nur noch als Abo Modell verfügbar sein soll. Sollte das tatsächlich passieren, ist Windows für mich gestorben. Abo Software verwende ich prinzipiell niemals. Dann müsste ich auch für mich selbst unbedingt eine Media-Buddy Version haben, die unter Linux lauffähig ist. Meine anderen Programme verwenden kein .json und funktionieren alle mit Wine. Ausgerechnet das komplexeste und wichtigste Programm aber nicht, was ich wirklich jeden Tag verwende und für das es unter Linux nicht mal ansatzweise eine Alternative gibt.

    Danke schon mal.