VOICE Homepage: http://de.os2voice.org |
Mai 2003
[Inhaltsverzeichnis]
|
Von Thomas Klein © Mai 2003 |
Als ich ursprünglich die Idee zu dieser Artikelreihe hatte, wollte ich die Anfänger erreichen - auch die REXX-Anfänger. Bis auf einige kleine Ausnahmen haben wir bisher aber nur Objekte und Methoden in DrDialog besprochen und REXX selbst eigentlich außer Acht gelassen. Heute werden wir daher den "GUI-Kram" einmal vergessen und eine Einführung in das "reine" REXX durchziehen. Wenn Sie also kein OS/2-REXX-Neuling sind, dürfen Sie diese Ausgabe gerne überspringen. ;-)
Im heutigen Teil schauen wir uns an, was es an Besonderheiten hinsichtlich
Variablen und einigen grundlegenden Befehlen und Funktionen in REXX zu beachten
gibt. Um das Erstellen von Skripten zu vermeiden, die lediglich aus einer oder
zwei Zeilen Code bestehen um REXX' Verhalten zu testen, verwenden wir ein
großartiges Hilfsprogramm zum "Spielen" mit REXX: Es nennt sich
REXXTRY
und eigentlich müßte es auch auf Ihrem System
direkt über Befehlszeileneingabe startbar sein. Probieren Sie's mal aus -
öffnen Sie eine Befehlszeilensitzung (ein OS/2-Fenster) und geben Sie
rexxtry
ein. Falls Sie Ulrich Möllers XWorkplace zusammen mit
dem XCenter verwenden, können Sie natürlich auch den Menüpunkt
Ausführen...
im XCenter-Button verwenden und dort rexxtry
eingeben. In beiden Fällen sollten Sie danach etwas sehen, was so aussieht
wie...:
Wenn rexxtry nicht startet, müssen Sie prüfen, ob es
sich in einem Verzeichnis befindet, das Teil der PATH-Variable
Ihrer CONFIG.SYS
ist. Oder - um es anders zu formulieren - Sie müssen es dann aus
dem Verzeichnis heraus starten, in dem es sich befindet. Suchen Sie
nach einer Datei namens rexxtry.cmd. Standardmäßig sollte
sie sich im Verzeichnis \OS2 auf dem OS/2-Installationslaufwerk
befinden.
Rexxtry
kann auf unterschiedliche Arten verwendet werden,
je nach dem wie es gestartet wurde. In unserem Beispiel verwenden wir
beim Aufruf keinerlei Parameter und somit startet es im "interaktiven
Modus", in dem jede Eingabezeile einzeln verarbeitet (interpretiert)
wird.
Um rexxtry
zu beenden, geben Sie einfach exit
ein. Übrigens: Wie immer bei Befehlszeilen werden auch hier die
Eingaben jeweils durch Drücken der Eingabetaste
abgeschlossen...
Um mit einer kleinen Besonderheit zu REXX zu beginnen, versuchen wir 'mal,
unser Programm "Hallo" sagen zu lassen, indem wir den say
-Befehl
verwenden.
say
wird verwendet, um "einen Ausdruck in den
Standard-Ausgabedatenstrom zu schreiben". Da wir den interaktiven Modus
von rexxtry verwenden und keine zusätzlichen Tricks und Kniffe
benutzen, ist der "Standard-Ausgabedatenstrom" in unserem Fall
schlichtweg der Bildschirm. Wir zeigen also etwas an. Was aber hat es
nun mit "Ausdruck" auf sich? Um es einfach zu halten, lassen Sie es mich
so sagen: Das kann entweder ein Literal sein (eine konstante
Zeichenkette in Anführungszeichen), eine Variable oder eine
Funktion. In den beiden letzten Fällen wird also entweder der
Inhalt der Variable bzw. der Rückgabewert aus der Funktion
ausgegeben.
Um endlich 'mal etwas zu tun, sagen wir Hallo, indem wir in
rexxtry eingeben:
say "hallo"
Als Ergebnis erhalten wir eine einzelne Ausgabezeile mit dem Inhalt hallo
und eine gepunktete Trennzeile, die rexxtry immer nach dem Abarbeiten
einer Eingabe ausgibt (und die wir im Folgenden ignorieren werden).
Was das Ganze nun so besonders macht, ist die Tatsache, daß REXX's
Interpreter ein echt hilfsbereiter Kerl ist. Würden wir statt des
obigen Befehls eingeben...
dann würde das bedeuten: Zeige den Inhalt der Variablesay hallo
hallo
an - da wir nämlich keine Anführungszeichen verwenden.
Eigentlich würde man nun eine Meldung erwarten, die darüber
informiert, daß es keine Variable dieses Namens gibt. Das stimmt
zwar, aber... REXX stellt diese Variable automatisch zur Verfügung
und initialisiert sie direkt noch mit ihrem Namen (in
Großbuchstaben) als Inhalt und gibt daher aus:
HALLO
Ups! Das ist das Besondere an der Sache... natürlich sieht die Sache
anders aus, wenn wir selbst eine Variable namens hallo
definieren.
Geben Sie zuerst ein:
hallo = "Tach!"
Und dann:
say hallo
...und Sie werden sehen, daß nun folgendes ausgegeben wird:
Tach!
Denn nun existiert bereits eine Variable namens hallo
zum
Zeitpunkt des say
-Befehls und REXX gibt deren Inhalt aus (welcher
Tach!
lautet).
Vielleicht
haben Sie schon mit anderen Programmiersprachen gearbeitet und wissen
daher, daß alle ein unterschiedliches Verhalten beim
Formatieren relativ einfacher Ausgaben besitzen, besonders wenn
die Ausgaben aus einer Kombination von Literalen und Variablen
bestehen. REXX bildet da keine Ausnahme - allerdings ragt es aus der
Masse hervor, weil es sich extrem präzise verhält, wenn es um
das geht, was "hinter" dem say
-Schlüsselwort steht. Machen wir doch 'mal weiter und geben ein:
sdl = 42
say "Der Sinn des Lebens ist:" sdl
Daraus wird:
Der Sinn des Lebens ist: 42
Sie fragen sich jetzt wohl, was daran so besonders ist... nun, da steht doch eine Leerstelle zwischen dem Doppelpunkt und der 42. Haben wir gesagt, daß die da hin soll? Ich befürchte ja - um es zu verdeutlichen, geben Sie ein:
say "Der Sinn des Lebens ist:"sdl
Daraus wird nun:
Der Sinn des Lebens ist:42
Und nun - um ein letztes Beispiel anzugeben - geben Sie noch ein:
say "Der Sinn des Lebens ist:" sdl
(mit 7 Leerstellen zwischen dem Literal und dem Variablennamen) und ausgegeben wird entsprechend:
Der Sinn des Lebens ist: 42
Die Anzahl der Leerstellen in say
-Befehl
entspricht genau der, die in der Ausgabe verwendet wird, was nicht
gerade typisch für Programmiersprachen ist, soweit ich weiß.
Normalerweise wird eine Anweisung untersucht und in Schlüsselwort
und Parameter zerlegt, wobei die Anzahl der Leerstellen unerheblich
ist.
Da wir nun also schon eine Methode kennen, um Ausgaben in REXX zu
erzeugen, schauen wir uns doch noch einen Befehl an, um Eingaben zu
verarbeiten. Wir verwenden dafür den Befehl PULL
. Genau
genommen dient PULL
dazu, eine Zeile aus dem
Standard-Eingabedatenstrom zu holen. Da wir in unserer
rexxtry
-Sitzung
weder mit Warteschlangen noch mit Datenströmen herumgespielt
haben, wird REXX dadurch veranlaßt, auf die Eingabe einer
Zeile (Eingabe wird abgeschlossen mittels
Eingabetaste
) durch den Anwender zu warten. Geben Sie 'mal
ein:
pull eingabe
Ja. Da wartet rexxtry nun auf Ihre Eingabe. Tippen Sie ruhig irgendeinen Satz ein, der Ihnen gerade durch den Kopf geht - Hauptsache, er besteht (zumindest teilweise) aus Kleinbuchstaben, denn das wird gleich interessant... nach Ihrer Eingabe geben Sie folgenden Befehl ein:
say eingabe
Und nun sehen Sie sich das an! Da hat der doch
tatsächlich alles in Großbuchstaben umgewandelt! Aber so ist
es nun mal - wenn Sie die Eingabe genau so benötigen, wie Sie
gemacht wurde, dann müssen Sie eine andere Funktion namens
PARSE
in Kombination mit PULL
verwenden, so wie
in...
parse pull eingabe
Jetzt wird nach
say eingabe
genau das ausgegeben, was auch eingegeben wurde. Natürlich gibt es zu
PARSE
noch einiges mehr zu erzählen, aber das werden wir uns
in einer späteren Ausgabe antun.
Nun
kennen wir also schon das Grundgerüst, um Eingaben und Ausgaben in
REXX zu erzeugen. Leider nützt uns das aber innerhalb DrDialog
nichts, denn dessen Umgebung ermöglicht den Einsatz der oben
beschrieben Funktionen für Ein-/Ausgabezwecke nicht -
andererseits: Wozu sollte das gut sein? In DrDialog werden Ausgaben
gemacht, indem die Texteigenschaft eines Objektes verändert wird
und Eingaben werden durch das Auswerten eines Texteingabefelds
erreicht. Der say
-Befehl ist zwar in DrDialog sehr
nützlich, um den Programmablauf zu kontrollieren (da seine Ausgaben
im Fenster des Laufzeit-Monitors landen), aber sowohl say
als auch
pull
ermöglichen Ihnen, auch außerhalb DrDialog
einfache Skripte zu erstellen.
Wie
dem auch sei: Für's erste bleiben wir lieber bei REXX-Elementen,
die Sie auch in DrDialog einsetzen können. Schauen wir uns doch
'mal an, wie mathematische Berechnungen in REXX gemacht werden.
In REXX werden mathematische Berechnungen
einfach durch Angabe der entsprechenden Formel gemacht, wobei die
übliche Notation mit PLUS, MINUS, STERN (für Multiplikation)
und SLASH (der "normale" Schrägstrich für Division) verwendet
wird. Wie üblich gelten auch hierbei die Standardregeln der
Algebra - das heißt, die Berechnung erfolgt von links nach rechts,
wobei Klammerausdrücke Vorrang haben und die aus der Schulzeit
bekannte Regel "Punktrechnung geht vor Strichrechnung" gilt. Ein paar
Beispiele:
ergebnis = 12 + 4
ergebnis
enthält danach den Wert 16ergebnis = ergebnis + 1
ergebnis
wird um 1
erhöht
ergebnis = a - 5
ergebnis
enthält den um 5
verringerten Wert der Variable a
cents = euros * 100
cents
enthält danach den Wert der Variable euros
multipliziert mit 100
euros = cents / 100
euros
enthält danach den Wert der Variable cents
geteilt durch 100
say 100 + 17 * (3 - 1)
134
: Die Multiplikation wird vor der Addition
durchgeführt wobei die Berechnung der Formel in Klammern zuerst
geschieht...Beachten Sie, daß einige der obigen Beispiele als Teil eines
größeren Kontext zu verstehen sind: Wenn Sie beispielsweise
den Wert einer Variablen um 1 erhöhen wollen, muß der
Inhalt der Variablen numerisch sein, sonst erhalten Sie eine
Fehlermeldung. Dasselbe gilt auch für das Beispiel ergebnis = a -
5
: der Inhalt von a
muß numerisch sein, bevor
diese Anweisung erfolgt. In rexxtry
würden Sie zum Beispiel
folgendes eingeben:
cents = 3456
euros = cents / 100
say euros
...was dann 34.56
ausgeben würde.
Für die Deutschen Leser muß hier noch darauf hingewiesen werden, daß Nachkommastellen mittels eines Punkts
vom ganzzahligen Teil getrennt werden, wie es in den USA üblich
ist... das gilt auch für eigene Angaben von Nachkommawerten im
Programm. Sie müssen einen Punkt verwenden.
Exponentialrechnung erfolgt durch Angabe eines doppelten Sterns, wie z.B. in:
say "Der maximale dezimale Wert eines Bytes ist" 2 ** 8 -1
Schauen wir uns
erst einmal die Kommentare an. Kommentare werden verwendet, um
Informationen innerhalb eines Programms zu speichern, die keinen
ausführbaren Code darstellen, also vom Interpreter oder Compiler
nicht verarbeitet werden sollen. Damit werden einzelne Teile eines
Programms dokumentiert, um ein besseres Verständnis für den
Verarbeitungsablauf des Programms zu gewährleisten. Hinsichtlich
der Kommentare gibt es eine Besonderheit in REXX - nämlich,
daß ein REXX-Programm (oder Skript) mit einem Kommentar beginnen
muß. Ich habe 'mal irgendwo gelesen, daß OS/2 diese
Eigenschaft dazu verwendet, zwischen einem REXX-Skript und einer
Batch-Datei (Stapeldatei) unterscheiden zu können, bin mir aber
nicht sicher ob das stimmt.
Egal - nehmen Sie's einfach so hin: Ein
REXX-Skript muß mit einem Kommentar beginnen. (In DrDialog ist das
übrigens anders, da alles, was Sie dort codieren, innerhalb eines
Code-Rahmens stattfindet, den die Entwicklungsumgebung zur
Verfügung stellt.) Ein Kommentar beginnt mit der Zeichenfolge /*
(normaler Schrägstrich und Stern) und endet mit der umgekehrten
Zeichenfolge */
(Stern Schrägstrich). Ein einfacher Kommentar
würde also beispielsweise so aussehen:
/* das ist ein Kommentar */
Kommentare können sich auch über mehrere Zeilen erstrecken - das könnte dann wie folgt aussehen:
/*
Die folgende Routine wird für jede Zeile aufgerufen,
die aus der Eingabedatei gelesen wird. Jede Zeichenkette
innerhalb der Zeile, die zu dem angegebenen Suchbegriff
paßt, wird entfernt und der Rest wird dann als eine
Zeile in die Ausgabedatei geschrieben. Die Anzahl der
gefundenen Zeichenketten in der Zeile wird als return
code an die aufrufende Routine zurückgegeben.
*/
Wenn sich ein Kommentar über mehrere Zeilen erstreckt, kann es
mühsam werden, auf den ersten Blick Code von Kommentar zu
unterscheiden. Daher werden Sie - meistens - längere Kommentare in
REXX-Skripten in einer anderen Form vorfinden. Programmierer bevorzugen
meist eine Abfolge von einzelnen Kommentarzeilen wie...:
/* die folgende Routine wird für jede Zeile aufgerufen, */
/* die aus der Eingabedatei gelesen wird. Jede Zeichenkette */
/* innerhalb der Zeile die zu dem angegebenen Suchbegriff */
/* paßt wird entfernt und der Rest wird dann als eine */
/* Zeile in die Ausgabedatei geschrieben. Die Anzahl der */
/* gefundenen Zeichenketten in der Zeile wird als return */
/* code an die aufrufende Routine zurückgegeben. */
Der Grund hierfür liegt einfach in der besseren Lesbarkeit solcher Kommentare: Man erkennt diesen Block sofort als einen "Kommentar" verglichen mit einem mehrzeiligen Textblock, der lediglich eine einleitende Kommentarkennung hat und die unter Umständen erst nach Blättern im Code gefunden und erkannt werden kann. Kommentare müssen übrigens auch nicht alleine auf einer Zeile stehen. Sie werden es bei kurzen Kommentaren bestimmt bevorzugen, diese mit dem Code zusammen auf einer Zeile zu schreiben, wie in folgendem Beispiel:
euro = dm / 1.95583 /* konvertiere DM-Betrag in Euro */
Und nun kommen wir zu den Anführungszeichen. REXX unterstützt sowohl einfache als auch doppelte Anführungszeichen als gleichbedeutend. Die beiden folgenden Anweisungen sind daher auch gleichbedeutend:
say "hallo"
say 'hallo'
Das einige, das Sie dabei beachten müssen ist, daß Sie für zusammengehörende Anführungszeichen auch denselben Typ (einfach/doppelt) verwenden, sonst erkennt REXX das nicht und beschwert sich mit der Meldung "unmatched quote or *". Das würde beispielsweise passieren bei einer Anweisung wie...:
say 'hallo"
REXX' Fähigkeit, beide Typen von Anführungszeichen zu unterstützen, ist dann sehr nützlich, wenn der zu verarbeitende (anzuzeigende) Text selbst Anführungszeichen enthält:
say "Die angegebene Datei gibt's nicht!"
oder
say 'Mein Chef sagt: "Wir müssen unsere Kernkompetenz stärker fokussieren." '
Doch selbst mit einem verständnisvollen Interpreter stößt man irgendwann auf eine Situation, in der im Text selbst dasselbe Anführungszeichen enthalten ist, das auch zur Eingrenzung des Textes selbst verwendet wird. Im Normalfall passiert das dann, wenn der Text beide Typen von Anführungszeichen verwendet. In REXX können Sie das dennoch bewerkstelligen, indem das Anführungszeichen im Text gedoppelt wird... Hmm.. es wird unübersichtlich. Hier ein Beispiel:
say 'Das Original von "That''s just the way it is." stammt aus Bruce Hornsby''s Feder und 2PAC hat''s gecovert.'
Ich schlage vor, Sie spielen ein wenig in rexxtry herum um selber ein Gespür für das Thema "Anführungszeichen" zu entwickeln.
Tja, für heute wär's das erst mal. In der nächsten Ausgabe schauen wir uns REXX' Konstrukte für bedingte Ausführung (if, select), Iterationen (Schleifen), Unterroutinen und Funktionen an. In Teil 10 kümmern wir uns um die Fülle von Funktionen, die REXX zur Zeichenkettenverarbeitung bietet, und nehmen uns auch einige der RexxUtils-Funktionen vor. Danach, in Teil 11 kommen wir zurück zu DrDialog und lernen, wie man mit mehreren Dialogen innerhalb eines Programms umgeht. Was danach kommt weiß ich noch nicht so genau - entweder beginnen wir dann mit unserer größeren Beispielapplikation oder wir schieben noch einen Teil mit "vergessenen" Punkten dazwischen... mal sehen. Bleiben Sie dran!
Daten und Quellen:
|
[Artikelverzeichnis]
editor@os2voice.org
[Vorherige Seite] [Inhaltsverzeichnis] [Nächste Seite]
VOICE Homepage: http://de.os2voice.org