PRIVATE Variable
Definition einer PRIVATE Variablen
PRIVATE Variablen werden dynamisch erzeugt und "entsorgt".
Eine PRIVATE Variable kann auf drei verschiedenen Wegen erzeugt werden:
- durch die (ausführbare!) Anweisung "PRIVATE cVar"
- durch eine Wertzuweisung "cVar := 'Heute'"
- durch die Anweisung PARAMETER in einer Funktion (die übergebenen Werte werden in die vorgegebenen Variablen übernommen)
In den beiden ersten Fällen wird eine Variable mit dem Namen cVar erzeugt.
FUNCTION TueIrgendEtwas LOCAL nI PRIVATE dHeute PARAMETER nEins, nZwei, lVier cZeit := Time()
Innerhalb dieser Funktion sind damit fünf PRIVATE Variable definiert: - dHeute
- nEins
- nZwei
- lVier
- cZeit (vorausgesetzt, es existiert keine PUBLIC oder STATIC Variable dieses Namens)
Zur Reihenfolge der Deklaration siehe ausführbare und nicht ausführbare Deklarationen.
Besonderheit bei der Definition
Da die PRIVATE Anweisung eine ausführbare Anweisung ist (im Gegensatz zu LOCAL, STATIC und FIELD), kann sie in Verbindung mit Makros verwendet werden:
cNewField := "nSumme" PRIVATE &cNewField cNewField := FieldName(1) PRIVATE &cNewField
Im ersten Fall wird eine PRIVATE Variable mit dem Namen nSumme erzeugt, im zweiten Fall eine PRIVATE Variable, die so heisst, wie das erste Feld in der aktiven DBF-Datei (ist keine DBF-Datei geöffnet und ausgewählt, gibt es einen Laufzeitfehler).
Unterschiede zu lexikalischen Variablen
PRIVATE Variablen können "on the fly" definiert und zerstört werden. Es muss keine Deklaration wie in anderen Sprachen durchgeführt werden. Dies ist sehr bequem und bringt die Gefahr mit sich, dass PRIVATE Variablen sich "überlagern" und damit ungewünschte Effekte erzeugen.
FUNCTION Main PRIVATE nIndex FOR nIndex := 1 TO 3 ? ProcName() + " " + Str(nIndex, 2) TueWas(nIndex) NEXT WAIT RETURN(.T.) FUNCTION TueWas(nWert) FOR nIndex := 1 TO 5 ? ProcName() + " " + Str(nWert * nIndex, 3) NEXT RETURN(.T.)
Bei Aufruf dieses Programms wird folgendes am Bildschirm ausgegeben:
MAIN 1 TUEWAS 1 TUEWAS 2 TUEWAS 3 TUEWAS 4 TUEWAS 5
In TueWas() wird nIndex angesprochen. Gäbe es diese Variable nicht (in unserem Beispiel wurde sie in Main() erzeugt), würde sie durch die Zuweisung in der FOR-Anweisung erzeugt. Da sie aber existiert, wird die existierende Variable verwendet. Nach dem Durchlauf der Schleife in TueWas() hat die Variable nIndex den Wert 6 und daher wird die Schleife in Main() beendet.
Um diesen Effekt zu vermeiden, muss die Funktion TueWas() leicht erweitert werden:
FUNCTION TueWas(nWert) PRIVATE nIndex FOR nIndex := 1 TO 5 ? ProcName() + " " + Str(nWert * nIndex, 3) NEXT RETURN(.T.)
Dadurch, dass eine explizite Deklaration aufgenommen wurde, wird in TueWas() eine separate PRIVATE Variable nIndex erzeugt, die nicht mehr mit der in Main() definierten identisch ist, sondern diese quasi überlagert.
Dieses Beispiel zeigt, dass die bequeme Anlage von PRIVATE Variablen durch Wertzuweisung auch ihre Schattenseiten hat, wenn es bereits eine PRIVATE Variable dieses Namens gibt.
Besonderheiten
Eine PRIVATE Variable ist an ihre Position im Call-Stack gebunden. (Sichtbar ist sie, wie das vorige Beispiel zeigt in der Funktion, in der sie deklariert wird, sowie in allen daraus aufgerufenen Funktionen bis zu dem Zeitpunkt, da die Funktion, in der sie deklariert wurde, endet.)
FUNCTION Main() ProcA() ProcB() RETURN(.T.) FUNCTION ProcA() ProcC() ... RETURN(.T.) FUNCTION ProcB() ProcC() ... RETURN(.T.) FUNCTION ProcC() cVar := "Hugo" RETURN(.T.)
cVar wird das erste Mal in folgender Aufruf-Konstellation (= Call-Stack) angesprochen:
Main() +---> ProcA() +---> ProcC()
cVar wird in ProcC() erzeugt und ist in dem Moment, in dem ProcC durch die RETURN-Anweisung verlassen wird, nicht mehr "adressierbar".
Wenn später über ProcB() ein weiterer Aufruf von ProcC() erfolgt, wird eine neue (!) PRIVATE Variable erzeugt:
Main +---> ProcB() +---> ProcC()
Auch für diese Variable endet ihre Lebenszeit, wenn ProcC mit RETURN verlassen wird.
Sichtbarkeit von PRIVATE Variablen
Genaueres findet sich hier: Lebenszeit und Sichtbarkeit der Variablen-Klassen