• Offizieller Beitrag

    Bevor ihr anfangt, solltet ihr zumindest "LUA für Anfänger" mal in groben Zügen durchlesen um einige Unterschiede zu AutoIt zu erkennen.
    Ich werde Bsp. von dieser Seite hier darstellen, jede Zeile kommentiert.

    Erste Schritte:

    Variablendeklaration:
    Wenn eine Variable nicht als "local" deklariert wurde, ist sie immer "global".
    Variablennamen bestehen aus Buchstaben/Ziffern/Unterstrich

    Zuweisungen:
    erfolgen, wie in AutoIt, mit "=". Aber als Vergleichsoperator dient "=="!
    Es gibt in LUA den Wert "nil" für "nichts". Das dient z.B. dazu Variablen zu löschen oder wird bei Fehlern ausgegeben.

    Kommentare im Skript:
    in einer Zeile: "--Kommentar"
    mehrzeilig:
    --[[ erste Zeile Kommentar
    Kommentarzeile 2
    Kommentarzeile 3
    Kommentar Ende ]]

    Text verknüpfen mit:
    ".." Bsp.: "Text: " .. stringvariable

    Ausgabe in Konsole:
    print()

    Nun mal probieren - Arrays heißen hier Table:

    Es lassen sich Feldnamen verwenden für Zugriffe mit: Table.Feldname

    Etwas ganz Tolles :thumbup:
    Funktionen lassen sich als Array (Table)-Elemente erstellen:

    Und wie sieht es mit Makros aus?
    Nun, Datum/Zeit lassen sich so ausgeben:

    Code
    t = os.date ("*t")
    print (t.year)
    print (t.month)
    print (t.day)
    print (t.hour)
    print (t.min)
    print (t.sec)

    Und zu guter letzt in diesem Beitrag - meine erste LUA-Funktion:

    • Offizieller Beitrag

    Was mir beim Skripten mit LUA an besonderen Unterschieden auffällt, werde ich mal extra erwähnen:

    Variablendeklaration/-Wertzuweisung
    - Variablen ohne Wertzuweisung können, genau wie in AutoIt, durch Kommata getrennt hintereinander deklariert werden.
    - Nach Deklaration einer Variablen mit Wertzuweisung darf keine weitere Deklaration mit Wertzuweisung durch Kommata getrennt erfolgen.
    - Aber: Es können weitere leere Variablen kommagetrennt deklariert werden.
    - Mehrere Deklarationen mit Wertzuweisung werden hintereinander geschrieben nur durch Leerzeichen getrennt.

    Code
    local a, b, c			-->> OK
    local a = 5, b = 6, c = 7	-->> FEHLER
    local a = 5, b, c		-->> OK
    local d = 5 e = 6 f = 7		-->> OK

    ContinueLoop
    Gibt es in LUA gar nicht. Hier muß man sich im Programmierverhalten umstellen. ContinueLoop ist strenggenommen eine 'GoTo'-Anweisung und somit wohl von den Entwicklern verpönt. :whistling:
    Ich habe einige, recht aufwändige Iterationskonstrukte gefunden, die ein Verhalten wie ContinueLoop ermöglichen sollen - aber solange das nicht nativ codiert ist verliert man dann im Code erst recht die Übersicht.

    Was mir fehlte, waren die kleinen Hilfsmittel zum Debuggen: DebugToConsole/~MsgBox.
    Ich habe dazu entsprechende Varianten erstellt. Die von Jos für AutoIt geschaffenen Varianten habe ich aber außen vor gelassen. Diese können nur simple Variablenformen erfassen, Arrays werden nicht erkannt. Ist allein mit RegEx auch nicht zu lösen.
    Meine Variante ist zwar etwas aufwändiger, erkennt aber auch Variablen"monster" der Form: "$arAA [ UBound( $arBB ) - 1 ] [ $i ]" ^^
    Einzige Bedingung: Der Cursor muß auf (oder links von) dem Variablenstamm stehen (hier also $arAA).
    In Lua-Skripten ist die Erkennung noch etwas schwieriger, da Variablen keinen markanten Anfang haben. Somit können Array(Table)-konstrukte nicht sicher erkannt werden, wenn Leerzeichen in den Klammern sind.
    Daher ist die Variablenerkennung für Lua-Skripte u.U. noch etwas fehlerbehaftet, also besser keine Leerzeichen in Klammern verwenden.

    Geändert: s. Post #4

    Zur besseren Wartbarkeit der eigenen Dateien und für gute Übersicht, empfiehlt es sich z.B. eine Datei "EigeneTools.lua" zu erstellen, in der man die allgemein verfügbaren Funktionen bereitstellt.
    Ich habe meine "EigeneTools.lua" mit angehängt, mit Funktionen für TimeStamp und DebugConsole/MsgBox, jeweils selbstselektierend für .lua oder .au3 .
    Diese darf aber erst nach Registrierung der EventClass geladen werden, damit Skripte, die auf Events zurückgreifen (z.B. TimeStamp), nicht ins Leere laufen.
    Damit MsgBox in LUA-Skripten möglich ist, muss ein zusätzliches Modul geladen werden:
    - angehängten Ordner "LuaLib" (entpacken) als Unterordner in "..\Scite\Lua" einfügen
    - in "SciTEStartup.lua" muß die Dll geladen werden, hier mal meine Startup:

    SciTEStartup.lua


    Um diese Debug-Module zu aktivieren, müssen zuerst die in SciTE4AutoIt aktiven Module abgeschaltet werden:
    - .au3 Datei im Editor öffnen
    - Ctrl+1 öffnet "SciTE Config"
    - "Tools Selection"
    - Checkboxen: 24, 25, 26 deaktivieren
    - "Update" klicken

    in: "..\SciTEUser.properties"
    einfügen:

    in SciTEUser.properties

    In meinem SciTE4AutoIt funktioniert seltsamerweise die geladene Dll mit der MsgBox-Funktion nicht. Raupi hatte getestet und bei ihm läuft es in der Umgebung.
    Da ich selbst eine andere SciTE-Version verwende vermute ich mal, dass es zu Konflikten zwischen den beiden Versionen kommt. Wenn ihr nur ein SciTE installiert habt, sollte somit die MsgBox auch in Lua funktionieren.
    Syntax: shell.msgbox(TEXT, TITEL [,FLAG=0])
    Mehr über die Funktionen der 'shell' könnt ihr im Ordner LuaLib, in der shell.html lesen.

    • Offizieller Beitrag

    Ich habe die Variablenerkennung für die Debugging-Funktionen (Debug To Console/MsgBox) nochmal überarbeitet.
    Es werden jetzt alle Variablenkonstrukte in AutoIt erkannt, seien sie auch noch so verkapselt. :D
    Allerdings habe ich die Erkennung von Array-Variablen auf 4D begrenzt, das sollte reichen.
    Objektvariablen (sofern sie mit Methoden oder Properties verknüpft sind) werden ignoriert, da nicht feststellbar ist ob auch ein Wert zurückgegeben wird, der darstellbar ist.
    Auch die (äußerst schlampige) Syntax in AutoIt, dass zwischen den Klammernpaaren von Arrays beliebig viele Leerzeichen liegen dürfen ist berücksichtigt.
    Was ich aber rausgelassen habe, ist die Möglichkeit eine einzelne Variable über mehr als eine Zeile darzustellen - das ist mir zu pervers. ;)

    Dieses ist die Funktion zur Erkennung der Variablen:

    Spoiler anzeigen


    Am einfachsten in die bestehende "..\SciTE\LUA\AutoItTools.lua" diese Funktion einfügen. Unbedingt vor der Funktion: DebugMsgBoxAdd() einfügen.
    Anschließend in den Funktionen: DebugMsgBoxAdd() und DebugConsoleWriteAdd() folgende Änderung vornehmen:

    Code
    function AutoItTools:DebugMsgBoxAdd()
    --~ 	local word = self:GetWord2()
    	local word = GetVarFromCursor()
    Code
    function AutoItTools:DebugConsoleWriteAdd()
    --~ 	local word = self:GetWord2()
    	local word = GetVarFromCursor()

    Oder einfach eure AutoItTools.lua gegen die im Anhang austauschen.
    Viel Spaß dabei.

    Edit 29.12.2011: Noch zwei Ausnahmen eingefügt ( Cursor hinter schließender eckiger od. runder Klammer, die an Variable grenzt ).
    Edit 31.12.2011: progandys Anregungen übernommen

  • Da hast du dich mal wieder selbst übertroffen. Aber kann man statt

    Code
    editor:SetSel(iCaret, iCaret +1) 
    	local sSel = editor:GetSelText()


    nicht auch editor:GetCharAt(iCaret) verwenden?
    Und statt dem GoToPos, sollte das doch auch per editor: PositionFromLine(iLine) zu schaffen sein ;)

    • Offizieller Beitrag

    nicht auch editor:GetCharAt(iCaret) verwenden?

    Macht der Gewohnheit, so hatte ich angefangen in LUA. ;)

    Und statt dem GoToPos,

    Das GoToPos verwende ich hier um die vorherige Auswahl ( die ich mit GetCharAt gar nicht brauchen würde :rolleyes: ) wieder aufzuheben, rein optische Geschichte.

    Edit: Ahh, jetzt hab ich PositionFromLine() mit LineFromPosition() verwechselt. - Da hast du natürlich total recht, Danke für die Tipps.

    Edit2: Grad probiert: editor:GetCharAt() funktioniert nicht "Pane function / readable property / indexed writable property name expected"

    Edit3: 
    Habs gefunden, andere Syntax:
    char = editor.CharAt[pos]

  • Zitat

    Lua 5.2 Lua 5.2 was released on 16 Dec 2011.

    The main features in Lua 5.2 are yieldable pcall and metamethods, new lexical scheme for globals, ephemeron tables, new library for bitwise operations, light C functions, emergency garbage collector, goto statement, and finalizers for tables. The current release is Lua 5.2.0, released on 16 Dec 2011

    http://www.lua.org/versions.html#5.2
    Hasta la vista
    Salu22:)

    • Offizieller Beitrag

    Ich habe noch kleine Änderungen im Post #4 vorgenommen.

    Den Post von BasicOS werte ich mal als Info, dass eine neue LUA-Version released wurde.

    Nun aber zum eigentlichen Kern dieses Threads - ich will euch teilnehmen lassen an meinem Lernen in LUA.

    Heute: RegExp Pattern
    Es gibt einen deutlichen Unterschied zu AutoIt: LUA bietet nativ keine Regexp-Engine. - Aber: LUA arbeitet mit verschiedenen Pattern-gestützten Funktionen. Ähnelt RegExp, weist aber auch einige markante Unterschiede auf.
    Am Anfang habe ich oft geflucht, wenn es um das Erstellen von Pattern für LUA ging. Aber auch hier ist es ähnlich, wie in AutoIt: lange Probieren führt letztlich zur Erkenntnis. ;)
    Die Charakter Klassen sind ähnlich, wie bei AutoIt-RegExp

    Aber wir finden zwei bisher Unbekannte: %l und %u (Klein-/Großbuchstaben).
    Damit kann man Pattern teilweise sehr vereinfachen.
    Allerdings ist in diesem Zusammenhang auch anzumerken, dass es keine Möglickeit gibt per Schalter case-insensitiv zu prüfen (es gilt immer case-sensitiv). Somit muß ein Pattern, das "Func" in jeder Schreibweise erkennen kann, so aussehen:
    AutoIt: "(?i)func"
    LUA: "[Ff][Uu][Nn][Cc]"
    Das sieht nun nach mehr Schreibarbeit aus, wenn z.B. der Suchbegriff recht lang ist. Aber wozu gibt es denn Funktionen? Ich verwende dazu folgende Funktion:

    Code
    function InSens(s)
    	s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.upper(c),string.lower(c)) end)
    	return s
    end

    Damit sieht das obige Pattern dann so aus: InSens("func")
    Hier treffen wir auf: string.gsub(), einer StringReplace-Funktion. Hiermit suche ich nach einem Match für mein Pattern (hier "%a" = Buchstaben). Da ich als dritten Parameter eine Funktion einsetze, die ich genialerweise direkt im Aufruf erstellen kann, bildet die Funktion den Ersatzstring [ Match-Großbuchstabe Match-Kleinbuchstabe ] und ersetzt den Treffer damit. In einem optionalen 4-ten Parameter kann die Anzahl der Ersetzungen festgelegt werden.

    Die anderen Charakterklassen sind bekannt und brauchen keiner Erklärung.
    Bei den Quantifiern bietet LUA uns zusätzlich das "- 0 oder mehr Vorkommen" an. Also identisch zu "*" ? Keineswegs. Laut Doku besteht der entscheidende Unterschied darin, dass "-" immer den kürzest möglichen Match wählt, während "*" immer auf die längste Sequenz zugreift.
    Und dann gibt es noch ein echtes Schmankerl: %bxy
    Damit lassen sich sich "balanced strings", also ausgewogene Strings ermitteln. xy geben Start- und Endzeichen an. Üblicherweise findet es Anwendung für: '%b()', '%b[]', '%b%{%}', oder '%b<>', aber auch alle anderen Zeichen können Verwendung finden.
    Wichtig: Auf diese Matches können keine Quantifier angewendet werden.
    Das war übrigens das entscheidende Mittel um die Variablenerkennung von Array-Variablen zu realisieren.

    Wer hier nach der Pipe sucht um eine ODER-Abfrage zu gestalten wird enttäuscht. Das geht nicht. Da die Stringverarbeitung in LUA gefühlte 10-mal schneller abläuft als in AutoIt (mal ein Testskript zum Messen erstellen ;)) ist es aber kein Problem statt ODER verschiedene Pattern in einem Table (Array) abzulegen und dann abzuarbeiten.

    Anchor: Auch hier können wir Anker für Match am Stringanfang (^) und am Stringende ($) setzen.
    Capturing: Das Capturing ist weitestgehend analog zu dem in AutoIt. Aber was für mich völlig neu war: Verwendung des Captures im Pattern selbst.
    Bsp.:
    Wir haben einen String: Peter sagt: "Das war's dann"!
    Um den String einer Variablen zuzuweisen kommt man bei AutoIt schon ins Schwitzen wegen der Quotierung. Hier haben wir aber einen weiteren Stringbegrenzer, die doppelte eckige Klammer:
    s = [[Peter sagt: "Das war's dann"!]]
    Nun soll der Bereich zwischen den doppelten Anführungszeichen gefunden werden.
    posStart, posEnd, 1stCapture, 2ndCapture = string.find(s, "([\"'])(.-)%1")
    Da Pattern in LUA generell wie Strings behandelt werden, gilt auch im Pattern, dass Quota escaped werden müssen (anders als magic characters, die mit % maskiert werden, verwendet man dabei "\".
    Der erste Ausdruck sucht nach einem Quotierungszeichen im String und speichert das Ergebnis in %1. Dem kann jedes Zeichen, beliebig oft (kürzestes Vorkommen) folgen. Anschließend muß das gleiche Quotierungszeichen, wie beim ersten Fund, folgen. Dazu wird dann direkt mit %1 darauf verwiesen.
    string.find gibt als erste zwei Parameter die Trefferpositionen des Matches zurück. Position 3 enthält den ersten Match (oder nil wenn kein Treffer), sind mehrere Matches vorhanden, wird jeder Treffer als weiterer Wert zurückgegeben. Das gilt es zu beachten, um auch das gewünschte Ergebnis, hier 2ndCapture, zu verwenden.
    Lassen wir uns 2ndCapture ausgeben, erhalten wir, wie gewünscht: Das war's dann

    Und damit schließe ich für den Moment und wünsche euch ein schönes Restjahr.