$-Variablen ab V25.6 (2005-06) (in avanti geht's etwas anders, mehr dazu weiter unten )
In den Befehlen variable und write konnten bis V25.5 keine Variablen außer den zum System gehörigen und auch in den Exportparametern genutzten #u-Variablen verwendet werden. Deren Namensraum ist begrenzt, weil die Namen nur aus 1 oder 2 Zeichen bestehen können, und man kann damit keine selbsterklärenden Namen bilden.
Daher wurde ein eigenes, neues Konzept in die FLEX-Sprache eingebaut, das hier beschrieben wird:
Die Namen müssen mit $ beginnen, können ansonsten aber alle Zeichen enthalten bis auf das Leerzeichen, und sie können ziemlich lang sein. Groß- und Kleinschreibung sind signifikant. D.h. $Name, $nAmE und $NaMe sind drei verschiedene Variablen.
Man muß vorher nichts Besonderes tun, um $-Variablen zu nutzen. Die Existenz einer $-Variablen beginnt mit ihrer Besetzung, d.h. es gibt keine gesonderte Deklaration. Es gibt auch keine Typen: alles ist Text, wie bei den #u-Variablen.
Die Besetzung geht so:
var "abc" oder $Xyz abc
ins $Xyz
also genau wie bei #u-Variablen. Zusätzlich geht auch $Xyz=abc. Das mag als besser verständlich empfunden werden, vor allem wenn abc eine Zahl ist. Intern macht das keinen Unterschied, das Programm unterscheidet beim Speichern nicht zwischen Zahlen- und Textvariablen.
Zusatzmöglichkeit:
Wenn in der iV ein Text wie "$Abc xyz" steht, wird mit einem schlichten ins die Variable $Abc mit dem Wert xyz belegt (sog. dynamische Belegung).
Grundprinzip:
Die Sache ist sehr einfach: Wo bisher im FLEX ein #uxy stehen kann, da darf nun auch ein $name stehen, mit völlig gleicher Wirkungsweise. Wenn in $name ein Feldinhalt mit Unterfeldern steht, geht auch $name$x, um das Unterfeld $x herauszulösen, insbes. auch der Sonderfall $name$$, um den Feldanfang, den Abschnitt vor allen Unterfeldern, zu isolieren.
Ferner kann man in einem RTF-Hilfetext auch schreiben: %$Xyz , dann erscheint an der Stelle der Inhalt der Variablen $Xyz.
Zu beachten sind folgende Besonderheiten :
Ausnahmen:
1. if-Befehle mit $-Variablen innerhalb der Bedingung gehen nicht, wie etwa if >$name
2. Innerhalb von Manipulationsbefehlen geht so etwas wie (b"#uab"). Auch hier kann nicht statt #uab eine $-Variable stehen.
3. Ein if-Befehl analog zu if #nnn geht erst ab V26.7.
Dies umgeht man so:
var $name
if "" jump fehler
Ab V26.7 kann man aber schreiben:
if $name ...
if not $name ...
4. Manipulationsbefehle sind auch möglich, aber ein Spatium muß hinter dem Variablennamen stehen, also z.B.
var $name (b"xyz")
Hierbei kann man nur den Zugriff auf Unterfelder nicht mit einer Manipulation kombinieren, also etwa
var $name$x (b"xyz")
Als Ausweg wählt man Konstruktionen wie var $name (b"²x" e"²" b"xyz") oder
var $name$x
var (b"xyz")
Es gelten ferner folgende Regeln:
Besetzen (oben schon kurz angesprochen) kann man die freien Variablen auf zwei Arten.
Wenn $Titel eine $-Variable sein soll, dann weist man ihr folgendermaßen einen Wert zu:
(genau wie bei #u-Variablen schreibt man Name und Wert einfach nebeneinander hin!)
$Titel Die Glocke
Hinter dem Spatium darf nur Text auftreten, der dann komplett der Variablen zugewiesen wird bis zum Zeilenende;
//-Kommentare gehen in solchen Zeilen nicht, wie ja auch in den mit # beginnenden Zeilen.
[Das Spatium ist hier wichtig, anders als bei #u-Variablen, weil die Länge des Namens unbestimmt ist!]
oder auch (ebenfalls wie bei #u-Variablen)
var "Die Glocke" oder var #20 usw.
ins $Titel ins $Titel
In beiden Fällen werden die Zeichen nicht umcodiert, d.h. im ersten Fall, so genommen, wie sie im FLEX stehen. Führende oder am Ende stehende Leerzeichen werden bei ins $name nicht beseitigt, anders als bei Kategorien und #u-Variablen. Die Beseitigung kann man erreichen, indem man vor den ins-Befehl noch setzt var (f" " F" ") .
Was nicht geht, ist $Titel #20 u.dgl.! (Bei #u-Variablen geht das auch nicht)
Verwenden kann man die Variablen so:
var ... $Titel ... bzw. write ... $Titel ...
d.h. in jedem var- bzw. write-Befehl als Teil des cstring. Zwischen Anführungszeichen hat $ keine Wirkung, d.h. dort werden Variablennamen nicht erkannt!
Mit ... ist angedeutet, daß dort beliebige andere Elemente stehen können, die es in einem cstring geben kann.
Es geht auch indirekt, wenn z.B. in #uab die Zeichenfolge $Titel steht:
var #uab
var
danach steht der Inhalt von $Titel in der iV. (Denn der var-Befehl ohne Argument nimmt den Inhalt der iV als cstring.)
Bei Zuweisung eines neuen Wertes an dieselbe Variable geht der alte Wert verloren.
Löschen kann man eine Variable, indem man ihr nichts zuweist:
var ""
ins $Titel
Sie verschwindet dann aus der Liste, d.h. wird nicht mit einer leeren Zeichenkette belegt sondern ist dann gar nicht mehr da.
Und mit
var ""
ins $0 bzw. ins $1
löscht man alle kleinen bzw. großen Variablen auf einmal.
Prüfen, ob eine Variable belegt ist, geht so:
if not $name jump fehler
Innerhalb eines FLEXes sind alle Variablen global, d.h. in einem FLEX-Unterprogramm kann es keine lokalen Variablen geben. Für die Übersichtlichkeit sorgt man z.B. durch geeignete Namensgebung.
Aber nun noch eine sehr wichtige Besonderheit:
Wenn der Name mit einem Großbuchstaben oder @ beginnt, bleibt die Variable für die gesamte Sitzung erhalten, sonst nur innerhalb des FLEXes, d.h. bei Beginn eines neuen FLEXes ist sie nicht mehr da. Es gibt also zwei Variablenlisten: die "kleine" und die "große". Wir nennen sie $0- bzw. $1-Variable, der Grund wird unten noch klar.
Empfehlung: @ nicht als erstes Zeichen verwenden! Es soll in Zukunft für systemspezifische Funktionen reserviert sein.
Welchen Umfang ein solcher Variablenspeicher haben kann, ist schwer zu sagen. Bei Tests gab es mit 5000 (fünftausend) noch keine Probleme.
Es handelt sich um eine MFC-Listenklasse; deren Grenzen setzt Windows bzw. der darin verwendete Hash-Algorithmus.
Was damit nicht geht:
1. Einen Variablennamen trunkiert ansprechen (wie mit #ux. in den Exportparametern)
2. Die Variablenliste alphabetisch geordnet durchsehen und dabei bearbeiten/löschen (wie mit Alt+r die #u-Variablen)
3. Gezielt eine Anzahl Variablen mit einem Befehl löschen (wie mit #ux~ , um alle #uxy zu löschen)
Denn die Listenklasse arbeitet mit einem Hash-Algorithmus, und der läßt solche Dinge nicht zu. Dafür ist er schnell.
Was sich von selbst versteht:
Die #u-Variablen bleiben in allen Aspekten unverändert erhalten.
In den Exportparametern hat man keinen Zugriff auf die neuen $-Variablen, mit denen man sich folglich nebenwirkungsfrei austoben kann.
Zusatzbefehle
Der Umgang mit den $-Variablen wird dadurch komfortabler, denn man wird sie irgendwann nicht nur einrichten und benutzen wollen.
first $0
first $1
Setzt einen Zeiger auf das erste Element der "kleinen" bzw. "großen" Liste und holt dessen Inhalt in die iV.
next $0
next $1
holt das nächste Element aus der kleinen bzw. großen Liste in die iV, immer in der Form $name Text
Mit if no oder if "" kann man testen, ob es kein Element mehr gab. Somit kann man in einer Schleife die ganze Liste abarbeiten.
Zur Ordnung siehe den nächsten Punkt:
$0>dateiname
$1>dateiname
schreibt den Inhalt des kleinen bzw. großen Variablenspeichers in die Datei dateiname.
Eine erkennbare Ordnung gibt es dabei nicht - das ist typisch für Hash-Listen. D.h. die beim Einlesen gegebene Ordnung bleibt nicht erhalten und läßt sich auch nicht restaurieren.
Die Liste hat genau die Form $name Text, und das bedeutet, daß man sie unmittelbar wieder als FLEX zum Einrichten derselben Variablen benutzen kann.
Daraus ergibt sich:
SuperTip
Schreibt man in seinen _endflx.flx den Befehl $1>var.flx und in den _start.flx an das Ende den Befehl exec var, so hat man in der nächsten Sitzung immer sofort wieder die "großen" Variablen der letzten Sitzung. Selbstredend kann man dies nutzen, um alles mögliche an Information von Sitzung zu Sitzung zu transportieren (sog. "persistente" Variablen).
Hinweis: Auch die Phrasen kann man als persistente Variablen nutzen.
Klar, es wird sofort der Wunsch nach gezählten und assoziativen Arrays kommen, mehrdimensional natürlich! Aber alles auf einmal geht nicht. Immerhin gibt es durchaus Möglichkeiten!
ZusatzTip
Mit dem nachfolgenden kleinen FLEX kann man den Variablenspeicher nach einer Zeichenfolge durchsuchen lassen. Wenn es mal mehrere 1000 sind, kann das ja sinnvoll sein... Gefunden werden sowohl die Namen wie die Inhalte der Variablen!
**************************************************************************
VS.FLX : Suche in den $1-Variablen nach einer bestimmten Zeichenfolge
2005-06-20 Gross-/Kleinschreibung egal
ask Suchwort
Eingegebenes Suchwort in #usw speichern
ins #usw
first $1
if no mes Keine Variablen!;end
:loop
Variable in #uzs kopieren (Form ist immer $Name Text)
ins #uzs
Darin nach dem Inhalt von #usw suchen (gross/klein egal)
(hinten . anhaengen, sonst wuerde das Suchwort nicht gefunden, wenn
es genau am Ende des Variablentextes steht!)
var #uzs "."
var (b"~#usw")
Wenn es vorkam, anzeigen
if not "" var #uzs;yes;if yes jump found
naechste Variable holen
next $1
if not no jump loop
mes Ende!
end
:found
var "Gefunden: " #uzs
mes
*************************************************************************
Zum Testen wurde eine Kurzliste des BachWerkeVerzeichnisses verwendet, darin standen 1360 Zeilen wie diese:
$Bwv20 O Ewigkeit, du Donnerwort
Diese Datei kann man so wie sie ist als FLEX laufen lassen, dann hat man 1360 "große" Variablen belegt!
Gibt man nach dem Einlesen diesen Befehl:
x var $BWV214\mes
so erscheint richtig: Tönet, ihr Pauken! Erschallet Trompeten!
Sonderfall avanti
In avanti gibt es vorerst (Dez. 2009) folgende zwei Dinge:
1. Eine besondere $-Variable mit dem schlichten Namen $. Das ist also quasi eine zweite interne Variable. Mit
ins $
kopiert man den momentanen Inhalt der normalen iV hinein, und mit
var $
holt man sich umgekehrt den Inhalt von $ in die iV.
2. $-Variablen mit Namen wie bei a99 gibt es zwar auch, aber mit folgenden Einschränkungen:
a) Der Unterschied zwischen klein und groß ist nicht relevant, weil ja stets nach Abarbeitung eines Jobs das Programm acon
wieder beendet wird. (Dennoch sind $a und $A verschiedene Variablen!)
b) Ein Befehl wie
var $abc$x
um gezielt ein Unterfeld im Text von $abc anzusprechen, geht noch nicht.
c) Ein if $name ... geht auch nicht. Man behilft sich mit
var $name
if ="" ...