PRIVATE Variable: Unterschied zwischen den Versionen

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
Zeile 10: Zeile 10:
- durch eine Wertzuweisung "cVar := 'Heute'"
- durch eine Wertzuweisung "cVar := 'Heute'"


- durch die Anweisung PARAMETER in einer Funktion (die übergebenen Werte werden in die vorgegebenen Variablen übernommen)
- 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.
In den beiden ersten Fällen wird eine [[Variablen|Variable]] mit dem Namen cVar erzeugt.


  FUNCTION TueIrgendEtwas
  FUNCTION TueIrgendEtwas
Zeile 20: Zeile 20:
     cZeit := Time()
     cZeit := Time()


Innerhalb dieser Funktion sind damit fünf PRIVATE Variable definiert:
Innerhalb dieser [[Funktion]] sind damit fünf [[PRIVATE Variable|PRIVATE]] Variable definiert:
- dHeute
- dHeute


Zeile 29: Zeile 29:
- lVier
- lVier


- cZeit (vorausgesetzt, es existiert keine PUBLIC oder STATIC Variable dieses Namens)
- cZeit (vorausgesetzt, es existiert keine [[PUBLIC Variable|PUBLIC]] oder [[STATIC Variable|STATIC]] Variable dieses Namens)


Zur Reihenfolge der Deklaration siehe [[ausführbare und nicht ausführbare Deklarationen]].
Zur Reihenfolge der Deklaration siehe [[ausführbare und nicht ausführbare Deklarationen]].

Aktuelle Version vom 17. Juni 2013, 16:16 Uhr

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