AutoIt/Nietypowe techniki programowania

Metaprogramowanie, metajęzyk, refleksyjność

edytuj

Metaprogramowanie - technika umożliwiająca programom tworzenie lub modyfikację kodu innych programów (lub ich samych). Język umożliwiający stosowanie tej techniki nazywamy metajęzykiem.

Jeżeli metajęzyk umożliwia modyfikację własnego kodu, nazywany jest metajęzykiem refleksyjnym, a proces programowanie z użyciem tego mechanizmu, programowaniem refleksyjnym.

W Autoit istnieje możliwość użycia zmiennej łańcuchowej (stringu) jako elementu treści programu. Dzięki temu sam kod programu może być traktowany w sposób podobny jak zawarte w nim dane i modyfikowany dynamicznie w trakcie wykonywania.

Technika ta, rzadko realizowana w innych językach programowania, umożliwia w pewnych przypadkach uzyskanie efektów, których osiągnięcie innym sposobem byłoby trudne i pracochłonne.

Stringami mogą być:

- nazwy zmiennych

- nazwy funkcji

- wyrażenia (ten przypadek jest szczególnie interesujący)


W dalszej części rozdziału opiszę jak osiągnąć taki efekt i jakie korzyści można z niego mieć.

Jak to w AutoIt przeważnie bywa, wszystko jest realizowane za pomocą odpowiednich funkcji.

String jako nazwa zmiennej

edytuj

Funkcja Assign

edytuj
Assign ("nazwa_zmiennej", wartość_zmiennej [, flaga])

Funkcja nadaje wartość (i ewentualnie tworzenie) zmiennej o podanej nazwie. Zwraca 1 gdy sukces, lub 0 gdy wystąpił błąd.

"nazwa_zmiennej" - nazwa zmiennej musi być utworzona zgodnie z ogólnymi zasadami tworzenie nazw zmiennych, należy jednak pominąć prefiks $ (np. zmienna_1 a nie $zmienna_1). Można nadawać wartości zmiennym wcześniej utworzonym w sposób klasyczny. Zmienna nie może być tablicą.

wartość_zmiennej - wartość nadawana tworzonej zmiennej

flaga - określa sposób tworzenia zmiennej

0 - zmienna jest tworzona jeżeli nie istnieje (wartość domyślna)
1 - tworzenie zmiennej o zakresie lokalnym
2 - tworzenie zmiennej o zakresie globalnym
4 - błąd jeżeli zmienna nie istnieje


Funkcja Eval

edytuj
Eval ("nazwa_zmiennej")

Funkcja zwraca wartość zmiennej o nazwie podanej jako parametr. Jeżeli wystąpił błąd funkcja zwraca pusty string "", a makro @error przyjmuje wartość 1.

"nazwa_zmiennej" - nazwa zmiennej zgodna z ogólnymi zasadami tworzenie nazw zmiennych, należy jednak pominąć prefiks $ (np. zmienna_1 a nie $zmienna_1). Można odczytywać wartości zmiennych wcześniej utworzonym w sposób klasyczny. Zmienna nie może być tablicą.

Przykład zastosowania:

Przypuśćmy, że musimy utworzyć 99 zmiennych wg schematu $x1=1, $x2=2 ... $x99=99. W klasyczny sposób trzeba by 99 razy użyć instrukcji przypisania.

Było by to bardzo pracochłonne i rozwlekłe. Można jednak inaczej:

For $i=1 to 99
   Assign("x"&$i, $i, 1)
Next
MsgBox(0, "", Eval("x66"))

Od wersji 3.3.12 możliwe jest odczytanie tak utworzonych zmiennych w sposób klasyczny (próba klasycznego odczytania wartości zmiennej dla wcześniejszych wersji AutoIt'a powodowała błąd):

For $i=1 to 99
   Assign("x" & $i, $i)
Next
MsgBox(0, "", $x66)  ;błąd niezadeklarowanej zmiennej

Dla wcześniejszych wersji niż 3.3.12 trzeba było użyć dyrektywy #forcedef:

For $i=1 to 99
   Assign("x" & $i, $i)
Next
#forcedef $x66
MsgBox(0, "", $x66)

Funkcja Assign bez problemu nadaje wartość zmiennym utworzonym w sposób klasyczny:

Local $txt
Assign("txt", "wasta")
MsgBox(0, "", $txt)

a funkcja Eval odczytuje te zmienne:

$txt = "wasta"
MsgBox(0, "", Eval("txt"))

Funkcja IsDeclared

edytuj
IsDeclared ("nazwa_zmiennej")

Funkcja sprawdza czy została utworzona zmienna o podanej nazwie. Zwraca:

1 - gdy zmienna jest globalna

-1 - gdy zmienna jest lokalna

0 - gdy zmienna nie została utworzona

Działa ze zmiennymi utworzonymi klasycznie, jak i utworzonymi przez funkcję Assign.

Przykład:

For $i=1 to 99
   Assign("x" & $i, $i)
Next
MsgBox(0, "", IsDeclared("x66")) ;wyświetli 1
test()                          ;wyświetli -1
MsgBox(0, "", IsDeclared("b"))   ;wyświetli 0

Func test()
   Local $a
   MsgBox(0, "", IsDeclared("a"))
EndFunc


String jako nazwa funkcji

edytuj

Stringu jako nazwy funkcji można użyć tylko przy jej wywołani, lecz nie przy jej deklarowaniu. Służy do tego:


Funkcja Call

edytuj
Call ( "nazwa_funkcji" [, param1 [, param2 [, paramN]]] )

Funkcja wywołuje funkcję o podanej nazwie i opcjonalnie przekazuje do niej parametry. Jeżeli sukces to zwraca wartość zwracaną przez wywołaną funkcję (makra @error i @extended mogą być także przez nią ustawione).

W przypadku błędu makro @error przyjmuje wartość 0xDEAD, a makro @extended 0xBEEF (jeśli funkcja nie istnieje lub podano niewłaściwą ilość parametrów).

Uwaga: Wywoływana funkcja od wersji 3.3.10.2 może być funkcją wbudowaną translatora, parametry mogą być przekazywane przez referencję.

Przykład:

MsgBox(0,"",Call("test",1,2,3))

Func test($a, $b, $c)
   Return $a+$b+$c
EndFunc


String jako wyrażenie

edytuj

O ile trudno znaleźć sensowne zastosowanie dla funkcji Call, to użycie stringu jako wyrażenia ma duży potencjał programistyczny.

Wyrażeniem jest w zasadzie wszystko to, czemu możemy wyliczyć jakąś wartość. Może ono zawierać liczby, zmienne, stałe, operatory arytmetyczne i logiczne, operatory relacji oraz wywołania funkcji tak wbudowanych jak i zdefiniowanych przez programistę. Do wartościowania wyrażenia opisanego za pomocą stringu służy:


Funkcja Execute

edytuj
Execute ( "string" )

Funkcja zwraca wartość wyrażenia opisanego stringiem. Jeżeli wystąpił błąd to zwraca pusty łańcuch, a makro @error przyjmuje wartość różną od zera.

"string" - string z opisem wyrażenia

Ponieważ string z opisem wyrażenia może pochodzić z zewnątrz programy, jest możliwe wykonanie wewnątrz programu fragmentu kodu wczytanego z dysku lub wpisanego bezpośrednio z klawiatury.

Kilka przykładów, które zaprezentują możliwości funkcji Execute.

$ex='MsgBox(0, "Test Execute:", "Ala ma Asa")'
Execute($ex)
$ex = "(1+2)^2-5/3"
MsgBox(0, "Test 2:", Execute($ex))
$a=2
$b=3
MsgBox(0, "Test 3:", Execute("$a=$b"))
MsgBox(0, "Test 4:", Execute("sin($a)+cos($a+$b)"))

MsgBox(0, "Test 5:", Execute("test($a, $b)"))

Func test($p1, $p2)
   Return $p1+$p2
EndFunc


Zmienna zawierająca nazwę funkcji

edytuj

Od wersji 3.10.2 w AutoIt wprowadzono możliwość przechowywania w zmiennej nazwy funkcji.

Przykład:

$vFunc = MsgBox
$vFunc(0, "Test", "To działa!")


FuncName

edytuj
FuncName ( $Functionvariable )

Funkcja zwraca w postaci stringu nazwę funkcji przechowywanej w zmiennej, lub string pusty gdy wystąpił błąd.

$Functionvariable - zmienna przechowująca nazwę funkcji

Przykład:

$hFunc = MsgBox
MsgBox(0, "Test", "Nazwa funkcji to: " & FuncName($hFunc))


IsFunc

edytuj
IsFunc ( $Variable )

Funkcja sprawdza czy zmienna zawiera nazwę funkcji. Zwraca 1 gdy funkcja jest zdefiniowana przez użytkownika, 2 gdy funkcja jest funkcją wbudowaną translatora, lub 0 gdy zmienna nie zawiera nazwy funkcji.

$Variable - sprawdzana zmienna

Przykład:

$hFunc = MsgBox
MsgBox(0, "Test", "Jaki to rodzaj funkcji: " & IsFunc($hFunc))


Na koniec użyteczny przykład, kalkulator zapamiętujący wzór funkcji i obliczający jej wartość dla różnych argumentów:

#include <GUIConstantsEx.au3>
GUICreate("Wprowadź wartość zmiennej i wzór funkcji", 360, 120, -1, 300)
$f1 = GUICtrlCreateInput(0, 50, 5, 200, 20)
GUICtrlCreateLabel("$x=", 25, 8, 20, 20)
$f2 = GUICtrlCreateInput("", 50, 35, 200, 20)
GUICtrlCreateLabel("f(x)=", 22, 38, 30, 20)
$btn = GUICtrlCreateButton("Oblicz", 40, 75, 60, 20)
GUISetState()

Do
   $msg = GUIGetMsg()
   $txt1 = GUICtrlRead($f1)
   $txt2 = GUICtrlRead($f2)
   If $msg = $btn Then
      $x=Execute($txt1)
	  $res = Execute($txt2)
      MsgBox(4096, "Wynik:", $res)
   EndIf
Until $msg = $GUI_EVENT_CLOSE


Niestandardowe struktury danych

edytuj

Struktura danych (ang. data structure) - sposób uporządkowania informacji w komputerze. Na strukturach danych operują algorytmy.

W zasadzie AutoIt posiada standardowo tylko dwie struktury danych, zmienne proste przechowujące pojedynczą wartość i tablice.

W rozdziale o bibliotekach DLL omówiona została także struktura (rekord), do której dostęp jest możliwy za pomocą stosownych funkcji.

Czasami jednak z pewnych względów optymalne będzie użycie innych struktur danych. Podczas tworzenia skryptu programista musi dokonać wyboru odpowiedniej struktury, aby uzyskać pożądany efekt. Niewłaściwy wybór może niekorzystnie wpłynąć na złożoność obliczeniową, co przekłada się na szybkość działania programu. Jest to szczególnie ważne przy operowaniu dużymi zbiorami danych. Z drugiej strony należy także uwzględnić łatwość implementacji danej struktury w konkretnym przypadku.

Tablica asocjacyjna

edytuj

Tablica asocjacyjna: (tablica skojarzeniowa, mapa, słownik, ang. associative array, map, dictionary) – nazwa dla powszechnie stosowanego w informatyce abstrakcyjnego typu danych, który przechowuje pary (unikatowy klucz, wartość) i umożliwia dostęp do wartości poprzez podanie klucza.

Standardowo AutoIt nie posiada możliwości posługiwania się tego typu tablicami. Można jednak używać tablic asocjacyjnych za pośrednictwem znajdującego się w systemie operacyjnym obiektu Scripting.Dictionary. Obiekt ten posiada kilka metod umożliwiających tworzenie i manipulowanie tablicami asocjacyjnymi.

Tworzenie tablicy

edytuj
$nazwa_tablicy = ObjCreate("Scripting.Dictionary")

Dodawanie elementów do tablicy (metoda .Add)

edytuj
$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)

Usunięcie elementu tablicy (metoda .Remove)

edytuj
$nazwa_tablicy.Remove($nazwa_klucza)

Usunięcie wszystkich elementów tablicy (metoda .RemoveAll)

edytuj
$nazwa_tablicy.RemoveAll

Odczyt elementu tablicy (metoda .Item)

edytuj
$wartosc_klucza = $nazwa_tablicy.Item($nazwa_klucza)

lub w skrócie:

$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)

Nadanie wartości elementowi tablicy (metoda .Item)

edytuj
$nazwa_tablicy.Item($nazwa_klucza) = $wartosc_klucza

lub w skrócie:

$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza

Odczytanie w postaci 1-wymiarowej tablicy wszystkich wartości tablicy asocjacyjnej (metoda .Items)

edytuj
$array = $nazwa_tablicy.Items

Odczytanie w postaci 1-wymiarowej tablicy wszystkich kluczy tablicy asocjacyjnej (metoda .Keys)

edytuj
$array = $nazwa_tablicy.Keys

Zmiana nazwy klucza (metoda .Key)

edytuj
$nazwa_tablicy.Key($stary_klucz) = $nowy_klucz

Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Exists)

edytuj
$i = $nazwa_tablicy.Exists($nazwa_klucza)

Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.

Ilość elementów tablicy asocjacyjnej (metoda .Count)

edytuj
$i = $nazwa_tablicy.Count

UWAGA: Nazwa klucza może być stringiem lub dowolną liczbą, wartość może być dowolnego typu. W nazwach kluczy obiekt rozpoznaje wielkość liter, tak więc np. Klucz1 i klucz1 to dwie różne nazwy.

Przykład:

#include <array.au3>

$dane = ObjCreate("Scripting.Dictionary") ;tworzenie tablicy asocjacyjnej

;dodawanie kolejnych pól w tablicy
$dane.Add("nazwisko", "Kowalski")
$dane.Add("imię", "Jan")
$dane.Add("wiek", 61)
$dane.Add("wzrost", 170)
$dane.Add("kolor_oczu", "niebieskie")
$dane.Add(6.66, "wyższe")

;odczyt danych z poszczególnych pól tablicy
MsgBox(64, "Tablica asocjacyjna", _
           "Pan " & $dane.Item("imię") & " " & $dane.Item("nazwisko") & _
	   " ma lat " & $dane.Item("wiek") & _
	   ", " & $dane.Item("wzrost") & " cm wzrostu" & _
	   " i oczy " & $dane.Item("kolor_oczu") & ".")

;odczytanie w postaci tablicy, wartości wszystkich pól tablicy
$arr = $dane.Items
_ArrayDisplay($arr)

;odczytanie w postaci tablicy, wszystkich kluczy tablicy
$arr = $dane.Keys
_ArrayDisplay($arr)

$dane("kolor_oczu") = "zielone" ;zmiana wartości
MsgBox(0, "Kolor oczu", $dane("kolor_oczu"))

;zmiana nazwy klucza
$dane.Key(6.66) = "wykształcenie"

;sprawdzenie czy istnieje podany klucz
MsgBox(0, 'Klucz "wykształcenie"', $dane.Exists("wykształcenie"))
MsgBox(0, "Ilość elementów", $dane.Count)

$dane.Remove("wykształcenie") ;usunięcie podanego klucza
MsgBox(0, 'Klucz "wykształcenie"', $dane.Exists("wykształcenie"))


UWAGA: Pozostałe struktury danych wymagają .NET Framework 4.5

Tablica mieszająca

edytuj

Za Wiki:

Tablica mieszająca lub tablica z haszowaniem (ang. hash table) to struktura danych, która jest jednym ze sposobów realizacji tablicy asocjacyjnej, tj. abstrakcyjnego typu danych służącego do przechowywania informacji, w taki sposób aby możliwy był do nich szybki dostęp. Tablica mieszająca umożliwia również szybkie porównywanie danych, np. fragmentów tekstów, plików, itp.

Elementy tablicy mieszającej są indeksowane liczbowymi indeksami generowanym przez funkcję mieszającą. Odwołania do przechowywanych obiektów dokonywane są na podstawie klucza, który dany obiekt (informację) identyfikuje. Na podstawie klucza funkcja mieszająca generuje indeks, po którym przeszukiwana jest tablica. Przy dużych tablicach taka metoda jest o wiele szybsza niż bezpośrednie wyszukiwanie po kluczu, jak w tablicy asocjacyjnej.

Ponieważ cały proces tworzenia indeksów i przeszukiwania jest przeprowadzany w tle przez procedury systemu operacyjnego, dla programisty samo operowanie tablicami asocjacyjnymi i mieszającymi w zasadzie niczym się nie różni.

Tworzenie tablicy mieszającej

edytuj
$nazwa_tablicy = ObjCreate("System.Collections.Hashtable")

Dodawanie elementów do tablicy (metoda .Add)

edytuj
$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)

Usuwanie elementu tablicy (metoda .Remove)

edytuj
$nazwa_tablicy.Remove($nazwa_klucza)

Usunięcie wszystkich elementów tablicy (metoda .Clear)

edytuj
$nazwa_tablicy.Clear

Odczyt elementu tablicy

edytuj
$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)

Nadanie wartości elementowi tablicy

edytuj
$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza

Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Contains)

edytuj
$i = $nazwa_tablicy.Contains($nazwa_klucza)

Sprawdzenie czy istnieje podana wartość (metoda .ContainsValue)

edytuj
$i = $nazwa_tablicy.ContainsValue($nazwa_klucza)

Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.

Ilość elementów tablicy mieszającej (metoda .Count)

edytuj
$i = $nazwa_tablicy.Count

Przykład:

$hash = ObjCreate("System.Collections.Hashtable") ;tworzenie tablicy mieszającej

;dodawanie elementów do tablicy mieszającej
$hash.Add("Polska", "Kraków")
$hash.Add("Niemcy", "Berlin")
$hash.Add("Francja", "Paryż")
$hash.Add("Rosja", "Moskwa")
$hash.Add("Czechy", "Praga")

;zmiana wartości klucza
$hash("Polska") = "Warszawa"

MsgBox(0, "Count", "W bazie jest " & $hash.Count & " pozycji.") ;ilość elementów w tablicy

$country = "Polska"
MsgBox(0, "Odczyt", "Państwo:  " & $country & @LF & _
					"Stolica:     " & $hash($country)) ;odczyt elementu z tablicy

;czy w tablicy jest dana wartość
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $hash.ContainsValue("Paryż"))

;czy w tablicy jest dany klucz
MsgBox(0, "Contains", "Czy w bazie jest Francja: " & $hash.Contains("Francja"))

$hash.Remove("Francja") ;usunięcie z tablicy elementu o zadanym kluczu
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $hash.ContainsValue("Paryż"))


SortedList

edytuj

Jest to odmiana tablicy asocjacyjnej, która w momencie tworzenia i modyfikacji jest domyślnie sortowana po kluczu. Zwiększa to czas tworzenia tablicy, lecz zmniejsza czas wyszukiwania informacji. Dostęp do tablicy może być realizowany po kluczu lub po indeksie.

Tworzenie SortedList

edytuj
$nazwa_tablicy = ObjCreate("System.Collections.SortedList")

Dodanie wartości do SortedList (metoda .Add)

edytuj
$nazwa_tablicy.Add($nazwa_klucza, $wartosc_klucza)

Usunięcie elementu o podanym kluczu (metoda .Remove)

edytuj
$nazwa_tablicy.Remove($nazwa_klucza)

Usunięcie elemenu o podanym indeksie (metoda .RemoveAt)

edytuj
$nazwa_tablicy.RemoveAt($indeks)

Usunięcie wszystkich elementów tablicy (metoda .Clear)

edytuj
$nazwa_tablicy.Clear

Odczyt elementu tablicy

edytuj
$wartosc_klucza = $nazwa_tablicy($nazwa_klucza)

Nadanie wartości elementu tablicy

edytuj
$nazwa_tablicy($nazwa_klucza) = $wartosc_klucza

Sprawdzenie czy istnieje klucz o podanej nazwie (metoda .Contains)

edytuj
$i = $nazwa_tablicy.Contains($nazwa_klucza)

Zwraca True gdy klucz istnieje, lub False gdy nie istnieje.

Sprawdzenie czy istnieje podana wartość (metoda .ContainsValue)

edytuj
$i = $nazwa_tablicy.ContainsValue($nazwa_klucza)

Zwraca True gdy wartość istnieje, lub False gdy nie istnieje.

Ilość elementów tablicy (metoda .Count)

edytuj
$i = $nazwa_tablicy.Count

Indeks elementu o podanym kluczu (metoda .IndexOfKey)

edytuj
$indeks = $nazwa_tablicy.IndexOfKey($nazwa_klucza)

Indeks pierwszego elementu o podanej wartości (metoda .IndexOf Value)

edytuj
$indeks = $nazwa_tablicy.IndexOfValue($wartosc_klucza)

Odczyt klucza o zadanym indeksie (metoda .GetKey)

edytuj
$nazwa_klucza = $nazwa_tablicy.GetKey($indeks)

Odczyt wartości o zadanym indeksie (metoda .GetByIndex)

edytuj
$wartosc_klucza = $nazwa_tablicy.GetByIndex($indeks)

Zmiana wartości pod zadanym indeksem (metoda .SetByIndex)

edytuj
$nazwa_tablicy.SetByIndex($indeks, $wartosc)

Przykład:

$SList = ObjCreate("System.Collections.SortedList") ;tworzenie tablicy mieszającej

;dodawanie elementów do tablicy mieszającej
$SList.Add("Polska", "Kraków")
$SList.Add("Niemcy", "Berlin")
$SList.Add("Francja", "Paryż")
$SList.Add("Rosja", "Moskwa")
$SList.Add("Czechy", "Praga")

;zmiana wartości klucza
$SList("Polska") = "Warszawa"

MsgBox(0, "Count", "W bazie jest " & $SList.Count & " pozycji.") ;ilość elementów w tablicy

$country = "Polska"
MsgBox(0, "Odczyt", "Państwo:  " & $country & @LF & _
					"Stolica:     " & $SList($country)) ;odczyt elementu z tablicy

;czy w tablicy jest dana wartość
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $SList.ContainsValue("Paryż"))

;czy w tablicy jest dany klucz
MsgBox(0, "Contains", "Czy w bazie jest Francja: " & $SList.Contains("Francja"))

$SList.Remove("Francja") ;usunięcie z tablicy elementu o zadanym kluczu
MsgBox(0, "ContainsValue", "Czy w bazie jest Paryż: " & $SList.ContainsValue("Paryż"))

;odczyt indeksu klucza
MsgBox(0,"IndexOfKey", "Indeks dla klucza 'Polska':  " & $SList.IndexOfKey("Polska"))

;odczyt indeksu podanej wartości
MsgBox(0,"IndexOfValue", "Indeks dla wartości 'Praga':  " & $SList.IndexOfValue("Praga"))

;odczyt klucza dla zadanego indeksu
MsgBox(0,"GetKey", "Klucz dla indeksu 2:  " & $SList.GetKey(2))

;odczyt wartości dla zadanego indeksu
MsgBox(0,"GetByIndex", "Wartość dla indeksu 2:  " & $SList.GetByIndex(2))

Lista – struktura danych służąca do reprezentacji zbiorów dynamicznych, w której elementy ułożone są w liniowym porządku. Elementy listy są indeksowane (indeksy rozpoczynają się od 0, podobnie jak w tablicach).

Także i ten typ danych nie jest standardowo dostępny w AutoIt, dlatego musimy posłużyć się obiektem System.Collections.ArrayList.

Podstawową zaletą używania list zamiast tablic jest wzrost wydajności. Dostęp do elementów listy jest o wiele szybszy.

Tworzenie listy

edytuj
$nazwa_listy = ObjCreate("System.Collections.ArrayList")

Dodawanie elementów na końcu listy (metoda .Add)

edytuj
$nazwa_listy.Add($wartosc)

Dodawanie elementu na pozycji o zadanym indeksie (metoda .Insert)

edytuj
$nazwa_listy.Insert($indeks, $wartosc)

Indeksy pozostałych elementów są zwiększane o 1.

Usunięcie pierwszego elementu o zadanej wartości (metoda .Remove)

edytuj
$nazwa_listy.Remove($wartosc)

Indeksy pozostałych elementów są zmniejszane o 1.

Usunięcie elementu o zadanym indeksie (metoda .RemoveAt)

edytuj
$nazwa_listy.RemoveAt($indeks)

Indeksy pozostałych elementów są zmniejszane o 1.

Usunięcie elementów o zadanym zakresie indeksów (metoda .RemoveRange)

edytuj
$nazwa_listy.RemoveRange($indeks, $ilosc_elementow_do_usuniecia)

Indeksy pozostałych elementów są zmniejszane o $ilosc_elementow_do_usuniecia.

Tworzenie nowej listy z elementów o zadanym zakresie indeksów (metoda .GetRange)

edytuj
$nowa_lista = $nazwa_listy.GetRange($indeks, $ilosc_elementow_do_kopiowania)

Usunięcie wszystkich elementów listy (metoda .Clear)

edytuj
$nazwa_listy.Clear

Odczyt elementu listy o zadanym indeksie (metoda .Item)

edytuj
$wartosc = $nazwa_listy.Item($indeks)

Zmiana wartości elementu listy o zadanym indeksie (metoda .Item)

edytuj
$nazwa_listy.Item($indeks) = $wartosc

Odwrócenie kolejności elementów listy (metoda .Reverse)

edytuj
$nazwa_listy.Reverse

Odczytanie ilości elementów listy (metoda .Count)

edytuj
$i = $nazwa_listy.Count

Kopiowanie zawartości listy do jednowymiarowej tablicy (metoda .ToArray)

edytuj
$array = $nazwa_listy.ToArray

Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)

edytuj
$i = $nazwa_listy.Contains($wartosc)

Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.

Przykład:

$aList = ObjCreate("System.Collections.ArrayList") ;tworzenie listy

;dodawanie elementów na końcu listy
$aList.Add("a")
$aList.Add("b")
$aList.Add("c")
$aList.Add("d")
$aList.Add("a")
$aList.Add(3.1415)
$aList.Add("wasta")
ViewList($aList, "LISTA")

$aList.Insert(3,"ble, ble, ble") ;wstawienie elementu na pozycji o indeksie 3
ViewList($aList, "Insert(3)")

$aList.Item(3) = 666
ViewList($aList, "Item(3)")

$aList.Reverse
ViewList($aList, "Reverse")

$aList.Remove("a")
ViewList($aList, "Remove 'a'")

$aList.RemoveAt(2)
ViewList($aList, "RemoveAt(2)")

$aList.RemoveRange(2, 3)
ViewList($aList, "RemoveRange(4,3)")

$str = $aList.ToArray
MsgBox(0, "LISTA", "Element o indeksie 1 = " & $str[1])

;szukanie elementu o zadanej wartości
MsgBox(0,"LISTA", "Czy jest element o wartości 'wasta': " & $aList.Contains("wasta"))

$aList.Clear ;usunięcie wszystkich elementów listy
MsgBox(0, "LISTA", "Ilość elementów = " & $aList.Count) ;ilość elementów listy

;funkcja wyświetlająca zawartość listy
Func ViewList($aList, $title="")
   Local $n = $aList.Count ;ilość elementów listy
   Local $txt = "Indeks | Wartość" & @LF

   For $i=0 To $n-1
      $txt &= "---------------------" & @LF
      $txt &= $i & "          | " & $aList.Item($i) & @LF ;odczyt elementu o zadanym indeksie
   Next
   MsgBox(0, $title, $txt)
EndFunc

Kolejka

edytuj

Kolejka (ang. queue) – liniowa struktura danych, w której nowe dane dopisywane są na końcu kolejki, a z początku kolejki pobierane są dane do dalszego przetwarzania (bufor typu FIFO, First In, First Out; pierwszy na wejściu, pierwszy na wyjściu).

Tworzenie kolejki

edytuj
$nazwa_kolejki = ObjCreate("System.Collections.Queue")

Dodawanie elementu do końca kolejki (metoda .Enqueue)

edytuj
$nazwa_kolejki.Enqueue($wartość)

Odczyt elementu z początku kolejki i jego usunięcie (metoda .Dequeue)

edytuj
$wartosc = $nazwa_kolejki.Dequeue

Odczyt elementu z początku kolejki bez jego usunięcia (metoda .Peek)

edytuj
$wartosc = $nazwa_kolejki.Peek

Usunięcie wszystkich elementów kolejki (metoda .Clear)

edytuj
$nazwa_kolejki.Clear

Odczytanie ilości elementów kolejki (metoda .Count)

edytuj
$i = $nazwa_kolejki.Count

Kopiowanie zawartości kolejki do jednowymiarowej tablicy (metoda .ToArray)

edytuj
$array = $nazwa_kolejki.ToArray

Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)

edytuj
$i = $nazwa_kolejki.Contains($wartosc)

Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.


Przykład:

#include <array.au3>

$queue = ObjCreate("System.Collections.Queue") ;tworzenie kolejki

;dopisywanie elementów do kolejki
$queue.Enqueue(3.1415)
$queue.Enqueue("a")
$queue.Enqueue("b")
$queue.Enqueue("c")
$queue.Enqueue("wasta")
ViewQueue($queue)

;odczyt elementu bez usuwania
MsgBox(0, "Peek", "Początek kolejki = " & $queue.Peek)
MsgBox(0, "Count", "Ilość elementów kolejki = " & $queue.Count)

;odczyt elementu z usunięciem z kolejki
MsgBox(0, "Dequeue", "Początek kolejki = " & $queue.Dequeue)
MsgBox(0, "Count", "Ilość elementów kolejki = " & $queue.Count)

;czy element o zadanej wartości jest w kolejce
MsgBox(0, "Contains", "Czy 'wasta' jest w kolejce: " & $queue.Contains("wasta"))

;usunięcie wszystkich elementów kolejki
$queue.Clear
MsgBox(0, "Clear", "Ilość elementów kolejki = " & $queue.Count)

;wyświetlenie zawartości kolejki
Func ViewQueue($queue, $title="KOLEJKA")
   Local $Array = $queue.ToArray ;kopiowanie kolejki do tablicy
   _ArrayDisplay($Array, $title)
EndFunc


Stos (ang. Stack) – liniowa struktura danych, w której dane dokładane są na wierzch stosu i z wierzchołka stosu są pobierane (bufor typu LIFO, Last In, First Out; ostatni na wejściu, pierwszy na wyjściu).

Tworzenie stosu

edytuj
$nazwa_stosu = ObjCreate("System.Collections.Stack")

Dodawanie elementu na górę stosu (metoda .Push

edytuj
$nazwa_stosu.Push($wartość)

Odczyt elementu z góry stosu i jego usunięcie (metoda .Pop)

edytuj
$wartosc = $nazwa_stosu.Pop

Odczyt elementu z góry stosu bez jego usunięcia (metoda .Peek)

edytuj
$wartosc = $nazwa_stosu.Peek

Usunięcie wszystkich elementów stosu (metoda .Clear)

edytuj
$nazwa_stosu.Clear

Odczytanie ilości elementów stosu (metoda .Count)

edytuj
$i = $nazwa_stosu.Count

Kopiowanie zawartości stosu do jednowymiarowej tablicy (metoda .ToArray)

edytuj
$array = $nazwa_stosu.ToArray

Sprawdzenie czy istnieje element o zadanej wartości (metoda .Contains)

edytuj
$i = $nazwa_stosu.Contains($wartosc)

Zwraca True gdy dana wartość jest w liście, w przeciwnym razie zwraca False.

Przykład:

#include <array.au3>

$stack = ObjCreate("System.Collections.Stack") ;tworzenie stosu

;dodawanie elementów na wierzch stosu
$stack.Push(3.1415)
$stack.Push("a")
$stack.Push("b")
$stack.Push("c")
$stack.Push("wasta")
ViewStack($stack)

;odczyt elementu z wierzchu stosu bez usuwania
MsgBox(0, "Peek", "Wierzch stosu = " & $stack.Peek)
MsgBox(0, "Count", "Ilość elementów stosu = " & $stack.Count)

;odczyt elementu z usunięciem ze stosu
MsgBox(0, "Pop", "Wierzch stosu = " & $stack.Pop)
MsgBox(0, "Count", "Ilość elementów stosu = " & $stack.Count)

;czy element o zadanej wartości jest na stosie
MsgBox(0, "Contains", "Czy 'wasta' jest na stosie: " & $stack.Contains("wasta"))

;usunięcie wszystkich elementów stosu
$stack.Clear
MsgBox(0, "Clear", "Ilość elementów stosu = " & $stack.Count)

;wyświetlenie zawartości stosu
Func ViewStack($stack, $title="STOS")
   Local $Array = $stack.ToArray ;kopiowanie stosu do tablicy
   _ArrayDisplay($Array, $title)
EndFunc


Uruchamianie skryptu

edytuj

Skrypty AutoIt można uruchamiać spod edytora SciTe wciskając klawisz F5. Po skompilowaniu skrypt uruchamia się jak każdy plik wykonywalny Windows.

Oprócz tych standardowych sposobów, są możliwe także inne mniej typowe.

Uruchamianie skryptów z wiersza poleceń

edytuj

Skompilowane skrypty AutoIt'a można uruchomić z wiersza poleceń (linii komend). Możliwe jest także przekazywanie parametrów do tak uruchamianych skryptów.

Służy do tego zdefiniowana w translatorze globalna tablica o nazwie $CmdLine. Tablica jest tylko do odczytu, inicjowana w momencie uruchomienia skryptu. Ma ona następującą strukturę:

$CmdLine[0] - ilość parametrów przekazanych w wierszu poleceń
$CmdLine[1] - wartość 1 parametru
    ...
$CmdLine[n] - wartość n-tego paramatru

Należy pamiętać, że wszystkie parametry przekazywane z wiersza poleceń są tekstami. Separatorem między parametrami są spacje. Jeżeli chcemy przekazać parametr zawierający spacje, należy ująć go w cudzysłowy.

Można maksymalnie przekazać 63 parametry.

Przykład wywołania skryptu:

myprog.exe 1 2 "Autoit to jest to!" Wasta

Tablica $CmdLine będzie zawierać następujące wartości

$CmdLine[0] = 4                    (ilość parametrów)
$CmdLine[1] = 1                    (string 1 parametru)
$CmdLine[2] = 2                    (string 2 parametru)
$CmdLine[3] = Autoit to jest to!   (string 3 parametru)
$CmdLine[4] = Wasta                (string 4 parametru)

Przykład skryptu wypisującego w konsoli listę parametrów, a w okienku MsgBox ich ilość (skrypt należy skompilować):

#AutoIt3Wrapper_Change2CUI=y

$iIL = $CmdLine[0]
If $iIL>0 Then
   For $i=1 To $iIL
      ConsoleWrite($CmdLine[$i] & @LF)
   Next
EndIf

MsgBox(64, "Ilość parametrów:", $CmdLine[0])

Oprócz tablicy $CmdLine zdefiniowana jest także globalna zmienna $CmdLineRaw, która przechowuje listę parametrów w postaci stringu. Ta zmienna jest także tylko do odczytu, inicjowana w momencie uruchomienia skryptu.

Przykład skryptu wypisującego w okienku MsgBox listę wprowadzonych parametrów (skrypt należy skompilować):

MsgBox(64, "Lista parametrów:", $CmdLineRaw)


Uruchamianie pojedynczej linii kodu z wiersza poleceń

edytuj

Można wykonać pojedynczą linię kodu bezpośrednio z wiersza poleceń:

AutoIt3.exe [/komunikat błędu] /AutoIt3ExecuteLine "wiersz kodu do wykonania"

Przykład:

AutoIt3.exe /AutoIt3ExecuteLine "MsgBox(4096, 'Witaj świecie!', 'Cześć!')"

Sposób ten jest możliwy także wewnątrz skryptu:

Run(@AutoItExe & ' /AutoIt3ExecuteLine "MsgBox(0, ''Witaj świecie!'', ''Cześć!'')"')


Uruchomienie skryptu AutoIt z wnętrza innego skryptu

edytuj

Metoda ta umożliwia uruchomienie nieskompilowanego skryptu z wnętrza innego skryptu AutoIt. Skrypt uruchamiający może być skompilowany lub nie. Dla skryptu skompilowanego niezbędne jest użycie dyrektywy #pragma compile(AutoItExecuteAllowed, True). Domyślnie dyrektywa ta jest ustawiona na False, co blokuje możliwość uruchamiania skryptów w ten sposób.

Jeżeli skrypt uruchamiający nie jest skompilowany, to dyrektywa #progma nie jest konieczna (zostanie zignorowana).

Jeżeli skrypt uruchamiający jest skompilowany, to w systemie nie musi być zainstalowany AutoIt, jednak uruchamiany skrypt musi mieć dostęp w swoim bieżącym folderze, do wszystkich UDF'ów dołączanych dyrektywą #include.

Przykład (skrypt uruchamiający):

#pragma compile(AutoItExecuteAllowed, True)
$sFile = "test.au3"
$iProcess = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sFile & '"')

Skrypt uruchamiany (plik ze skryptem uruchamianym musi mieć nazwę taką jaką podano w skrypcie uruchamiającym, w naszym przypadku jest to test.au3):

MsgBox(0,"","Działa!")
MsgBox(64,"","HURA!!!")