1. Übersicht
YAB ermöglicht die Aufteilung eines Programms auf mehrere externe Libraries.
Eine Library kann enthalten:
- Variablen
- Stringvariablen
- Arrays
- Subroutinen
- exportierte Subroutinen
Eine Library wird mit import eingebunden. Ihre von außen verfügbaren Bestandteile werden über den Namespace der Library angesprochen.
1. Übersicht
YAB ermöglicht die Aufteilung eines Programms auf mehrere externe Libraries.
Eine Library kann enthalten:
- Variablen
- Stringvariablen
- Arrays
- Subroutinen
- exportierte Subroutinen
Eine Library wird mit import eingebunden. Ihre von außen verfügbaren Bestandteile werden über den Namespace der Library angesprochen.
| import test1 rn=test1.test1() |
Dabei ist test1 der Namespace und test1() die exportierte Subroutine.
2. Libraries und Namespaces
Eine oder mehrere Libraries können importiert werden:
| import test1 import test2 import test3> |
Jede Library besitzt ihren eigenen Namespace. Dadurch können gleichnamige Variablen und Subroutinen verschiedener Libraries eindeutig unterschieden werden.
| a=test1.value b=test2.value n=test1.test() m=test2.test() > |
Der Namespace wird beim Zugriff vor den Namen des gewünschten Bestandteils gesetzt:
| namespace.sub() namespace.sub$() namespace.variable namespace.variable$ |
3. Exportierte Subroutinen und Rückgabewerte
Eine Subroutine, die außerhalb ihrer Library aufgerufen werden soll, wird mit export definiert:
|
export sub test1() return 10 end sub |
Der Aufruf erfolgt über den Namespace:
| n=test1.test1() |
Auch Subroutinen mit $ können exportiert werden:
|
export sub test2$() return "Hallo" end sub |
Aufruf:
| text$=test2.test2$() |
Das $ ist Bestandteil des Namens der Subroutine und muss beim Aufruf entsprechend angegeben werden.
Eine mit $ benannte Subroutine kann dabei auch einen numerischen Wert zurückgeben. Das $ bestimmt also nicht zwingend den Datentyp des return-Wertes.
Beispiel:|
export sub test$() return 123 end sub n=test.test$() |
Rückgabewerte können direkt zugewiesen oder unmittelbar weiterverarbeitet werden:
| n=test.get_number() text$=test.get_text$() print arraydim(test.get_array()) |
4. Parameterübergabe
Exportierte Subroutinen können einen oder mehrere Parameter erhalten.
|
export sub add(zahl) return zahl*2 end sub |
Aufruf:
| n=test.add(10) |
Mehrere Parameter:
| export sub add(zahl1,zahl2) return zahl1+zahl2 end sub |
Aufruf:
| n=test.add(10,20) |
Die Reihenfolge der übergebenen Werte entspricht der Reihenfolge der Parameterdefinition.
Dabei können auch unterschiedliche Werte übergeben werden:
|
export sub text$(text$,zahl) return text$+str$(zahl) end sub |
Aufruf:
| text$=test.text$("Wert: ",10) |
5. Zugriff auf Variablen
Variablen einer Library können über den Namespace angesprochen werden.
Numerische Variable:
| n=test1.b |
Stringvariable:
| text$=test1.d$ |
Allgemeine Formen:
| namespace.variable namespace.variable$ |
Damit kann eine Library neben ihren exportierten Subroutinen auch Daten für andere Programmteile bereitstellen.
6. local-Variablen
Eine mit local deklarierte Variable gehört zur jeweiligen Subroutine.
|
counter=100 export sub test() local counter counter=counter+1 return counter end sub |
Hier existieren zwei unterschiedliche Variablen:
| counter --> Library-Variable |
und:
| local counter --> lokale Variable der Subroutine |
Der Zugriff:
| test.counter |
bezieht sich auf die Library-Variable und nicht auf die lokale Variable.
Die lokale Variable wird bei jedem erneuten Aufruf der Subroutine neu initialisiert.
Beispiel:
|
export sub test() local counter counter=counter+1 return counter end sub |
Mehrere Aufrufe liefern:
|
test() --> 1 test() --> 1 test() --> 1 |
Eine local-Variable einer anderen Subroutine ist ebenfalls unabhängig, auch wenn sie denselben Namen besitzt.
| export sub test1() local counter counter=counter+1 return counter end sub |
| export sub test2() local counter counter=counter+10 return counter end sub |
7. Zugriff einer Library auf andere Libraries
Eine Library kann auf exportierte Subroutinen und Variablen anderer Libraries zugreifen.
Beispiel:
|
export sub test5() a=test1.test1() b$=test2.test2$() return a end sub |
Ebenso kann auf Variablen zugegriffen werden:
| n=test1.b text$=test2.d$ |
Dadurch können Libraries untereinander sowohl Funktionen als auch Daten verwenden.
Eine Library kann somit beispielsweise:
| a=test1.test1() b=test1.b |
verwenden.
8. Cross-Namespace-Aufrufe
Mehrere Libraries können miteinander kombiniert werden.
Beispielsweise:
main.yab|
|-- test1
|-- test2
|-- test5
test5 kann Funktionen und Variablen von test1 und test2 verwenden:
|
export sub test5() a=test1.test1() b$=test2.test2$() return a end sub |
Damit können größere Programme aus mehreren spezialisierten Libraries aufgebaut werden.
Eine Library kann dabei sowohl auf Subroutinen:
| test1.test1() |
als auch auf Variablen:
| test1.b |
anderer Namespaces zugreifen.
9. Arrays
Libraries können Arrays enthalten und Arrays über exportierte Subroutinen zurückgeben.
Beispiel:
|
dim numbers(3) numbers(1)=10 numbers(2)=20 numbers(3)=30 |
Eine exportierte Subroutine kann das Array zurückgeben:
| export sub test_numbers() return number end sub |
Der Rückgabewert kann über den Namespace direkt weiterverarbeitet werden:
|
print arraydim(test_array.test_numbers()) print arraysize(test_array.test_numbers(),1) |
Das gleiche gilt für String-Arrays:
|
print arraydim(test_array.test_id$()) print arraysize(test_array.test_id$(),2) |
Damit können numerische und String-Arrays über Namespace-Subroutinen zurückgegeben und direkt an Array-Funktionen übergeben werden, ohne sie vorher zwingend einer Variablen zuweisen zu müssen.
Beispielsweise:
| arraydim(test_array.test_numbers()) |
führt zunächst die Namespace-Subroutine aus und übergibt deren Array-Rückgabewert anschließend an arraydim().
Ebenso:
| arraysize(test_array.test_numbers(),1) |
oder:
|
arraydim(test_array.test_id$()) arraysize(test_array.test_id$(),2) |
Damit eignet sich der Namespace auch für den Austausch komplexerer Datenstrukturen zwischen Libraries.
10. Variablen und Subroutinen als gemeinsamer Namespace
Eine Library stellt über ihren Namespace unterschiedliche Bestandteile zur Verfügung.
Beispiel:
test1|-- test1()
|-- value
|-- text$
|-- Array
Diese können über denselben Namespace angesprochen werden:
|
n=test1.test1() n=test1.value text$=test1.text$ print arraydim(test1.get_array()) |
Der Namespace dient somit als gemeinsamer Namensraum für die von der Library bereitgestellten Subroutinen und Variablen.
11. Bestätigte Eigenschaften
Die Namespace-Funktionalität wurde anhand einer Testreihe mit insgesamt 16 Tests überprüft.
Dabei wurden folgende Bereiche getestet:
- Import mehrerer Libraries
- Namespace-Aufrufe
- exportierte Subroutinen
- Subroutinen mit und ohne $
- numerische Rückgabewerte
- String-Rückgabewerte
- Parameterübergabe
- mehrere Parameter
- unterschiedliche Parameter
- Zugriff auf Variablen über den Namespace
- Zugriff einer Library auf andere Libraries
- Kombination aus Subroutinen und Variablen verschiedener Namespaces
- Arrays als Rückgabewerte
- numerische Arrays
- String-Arrays
- direkte Übergabe von Array-Rückgabewerten an arraydim()
- direkte Übergabe von Array-Rückgabewerten an arraysize()
- Verhalten von local-Variablen
Insbesondere wurde bestätigt, dass ein Array-Rückgabewert direkt weiterverarbeitet werden kann:
| arraydim(test_array.test_numbers()) arraysize(test_array.test_numbers(),1) arraydim(test_array.test_id$()) arraysize(test_array.test_id$(),2) |
12. Kurzreferenz
| Funktion | Syntax |
| Library importieren | import name |
| Sub exportieren | export sub name() |
| $-Sub exportieren | export sub name$() |
| Sub aufrufen | name.sub() |
| $-Sub aufrufen | name.sub$() |
| Variable | name.variable |
| Stringvariable | name.variable$ |
| Ein Parameter | name.sub(wert) |
| Mehrere Parameter | name.sub(wert1,wert2) |
| Rückgabewert | return wert |
| Array zurückgeben | return array |
| Arraydimension | arraydim(name.sub()) |
| Arraygröße | arraysize(name.sub(),dimension) |
| Library-Variable | name.variable |
| Library-Stringvariable | name.variable$ |
13. Merksatz
import bindet eine Library ein, export stellt eine Subroutine nach außen bereit und der Namespace ermöglicht den eindeutigen Zugriff auf die Variablen und Subroutinen der Library.
| import meine_lib n=meine_lib.berechnen(10) text$=meine_lib.text$("Hallo") wert=meine_lib.variable text$=meine_lib.text$ print arraydim(meine_lib.get_array()) |
Damit können YAB-Programme in mehrere Libraries aufgeteilt und diese Libraries über Namespaces miteinander verbunden werden.