VOICE Homepage: http://de.os2voice.org |
Juli 2003
[Inhaltsverzeichnis]
|
Von Thomas Klein © Juli 2003 |
Es tut mir leid, daß es in der letzten Ausgabe keine Fortsetzung gab, aber wir hatten
eine Badezimmerrenovierung anstehen. Schmerzende Finger und extreme Ermüdungserscheinungen
in den Abendstunden verhinderten größere Schreibarbeiten - aber lassen Sie mich zuerst
einmal anmerken, daß mir in der vorherigen Ausgabe ein ziemlich dicker Fehler unterlaufen
ist, als es um den Befehl say
ging:
Und nun - um ein letztes Beispiel anzugeben - geben Sie noch ein:
(mit 7 Leerstellen zwischen dem Literal und dem Variablennamen) und ausgegeben wird entsprechend:say "Der Sinn des Lebens ist:" sdl
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.
Das ist leider kompletter Unfug. ;-)
Obwohl der letzte Absatz meine Zweifel andeutet, hätte ich das besser noch mal prüfen
sollen: Selbstverständlich wird die Anweisung vom REXX-Parser in Schlüsselwort
und Parameter zerlegt und danach intern wieder zusammengesetzt. Daher lautet die Ausgabe zu obigem
Beispiel korrekterweise:
Der Sinn des Lebens ist: 42
Jetzt hätte ich natürlich behaupten können, das sei nur ein Test gewesen um zu sehen, ob Sie alle aufpassen <g>, aber um ehrlich zu sein war es schlichtweg ein Fehler. Dennoch sind die anderen Beispiele aus dem Artikel korrekt. Jetzt fragen Sie mich bloß nicht, wie es sein kann, daß ich so etwas schreibe oder warum das bei meinen begleitenden Tests der Beispiele nicht auffiel. Ich weiß es nicht. Scheinbar lief an jenem Tag etwas falsch. Die Korrekturleser in unserem Team haben es entweder auch nicht bemerkt oder haben sich nicht getraut, etwas zu sagen... (?) Wir sind jedenfalls alle nur Menschen, und Menschen machen Fehler. Entschuldigen Sie diesen.
Okay, schauen wir uns ein paar Beispiele dazu an, was das im einzelnen bedeutet:
Eine Sequenz ist das, was wir schon aus früheren Beispielen kennen. "Grafisch" gesehen findet der Programmablauf ausschließlich von "oben nach unten" statt. Eine Anweisung wird nach der anderen abgearbeitet, so wie in
say "Bitte Namen eingeben (und die Eingabetaste betätigen)..."
parse pull name
say "Hallo" name
buchstaben = length(strip(name))
say "Boah - Ihr Name besteht aus" buchstaben "Buchstaben."
Gut, das ist jetzt ein relativ doofes Programm - aber lassen Sie sich davon nicht stören.
Es ist noch nicht einmal notwendig zu verstehen, was length(strip(name))
genau macht
- wichtig ist nur, daß es sich um einen typischen Batch-Ablauf handelt, der aus einzelnen
Befehlen (für Eingabe, Ausgabe und Funktionsaufrufen) besteht. Der Programmablauf beginnt
bei der ersten Anweisung und endet mit der letzten. Danach wird das Programm beendet.
Die schematische Bedeutung einer bedingten Verzweigung entspricht im Prinzip genau dem Vorgang, der stattfindet, wenn Sie am Ende eines Korridors vor zwei oder mehr Türen ankommen: In Abhängigkeit von einer bestimmten Entscheidung gehen Sie entweder durch die eine oder die andere. Sie können nicht durch beide Türen zur gleichen Zeit weitergehen. Um Ihnen zu zeigen, wie das aussehen könnte:
say "Bitte Namen eingeben (und die Eingabetaste betätigen)..."
parse pull name
say "Hallo" name
buchstaben = length(strip(name))
say "Boah - Ihr Name besteht aus" buchstaben "Buchstaben."
IF buchstaben < 5 THEN
say "...und das ist ziemlich kurz."
ELSE
say "...und das ist eher lang."
Das bedeutet, daß sich die beiden "Zweige" hinter der Verzweigung gegenseitig
ausschließen.
Kurz gesagt sieht die Syntax des IF
-Befehls so aus:
IF <Bedingung erfüllt> THEN <auszuführender Befehl>
Wichtig zu wissen ist, daß sowohl das Schlüsselwort "IF"
als auch die zu prüfende Bedingung und das Wort "THEN"
in derselben
Zeile stehen müssen, damit der REXX-Parser kapiert, was Sie da machen wollen. Ein
"Parser" ist übrigens ein Prozeß, der Daten analysiert und die für die
spätere Verarbeitung relevanten Informationen daraus "extrahiert" - eine Art
"Aufbereiter", wenn Sie so wollen. Der REXX-Parser analysiert den vom Programmierer
eingegebenen Quellcode und setzt daraus die Befehle zusammen, die der REXX-Interpreter dann
ausführt.
Der auszuführende Befehl kann entweder auch auf derselben Zeile angegeben werden oder in
der nächsten nicht-leeren Zeile - das bedeutet...
IF alter < 20 THEN say "Sie sind relativ jung."
und
IF alter < 20 THEN
SAY "Sie sind relativ jung."
und
IF alter < 20 THEN
say "Sie sind relativ jung."
...sind alle gültige Schreibweisen mit demselben Ergebnis. Es spielt auch keine Rolle, ob die Schlüsselwörter in Groß-, Kleinbuchstaben oder einer Kombination daraus angegeben werden. Innerhalb dieser Vorgaben können Sie auch beliebig viele Leerstellen zwischen den einzelnen Wörtern lassen. Beispiel:
IF alter < 20 then
say "Sie sind relativ jung."
(Beachten Sie: Hier wurde "then"
in Kleinbuchstaben angegeben.)
Jetzt erweitern wir das gerade Gelernte um den Faktor ELSE
:
Das englische Wort ELSE bedeutet "sonst" - und gibt in unserem Kontext an, was gemacht
werden soll, wenn die Bedingung nicht erfüllt ist. In unserer Verzweigung trennt ELSE
sozusagen die beiden "Zweige" voneinander. Allerdings ist ELSE optional, das
heißt man muß nicht unbedingt angeben, was mit den "anderen Fällen"
geschehen soll. Tut man es nicht, wird damit auch nichts gemacht; es werden nur die abgefragten
Fälle gesondert verarbeitet.
IF <Bedingung erfüllt> THEN <Befehl-1> ELSE <Befehl-2>
Sekunde noch! Wenn Sie das Ganze auf einer Zeile schreiben, wird der Parser ein Problem damit haben... nehmen wir 'mal folgende Anweisung:
IF alter < 20 then
say "Sie sind relativ jung."
ELSE say "richtig jung sind Sie auch nicht mehr."
Wenn die Variable "alter"
einen kleineren Wert als 20 enthält,
wäre die Ausgabe:
Sie sind relativ jung. ELSE say richtig jung sind Sie auch nicht mehr.
Das passiert, weil der Parser in diesem Fall alles nach dem ersten SAY
als
Bestandteil desselben interpretiert - also als Texte oder Variablennamen. Um ihm auf die
Sprünge zu helfen, müssen Sie entweder ein Semikolon einfügen
IF alter < 20 then
say "Sie sind relativ jung."
; ELSE say "richtig jung sind Sie auch nicht mehr."
oder (der "bessere" Weg) indem Sie einen Zeilenumbruch hinter dem ersten Befehl ("zwischen den Zweigen") einfügen:
IF alter < 20 then
say "Sie sind relativ jung."
ELSE say "richtig jung sind Sie auch nicht mehr."
Apropos "mehrere Zeilen": Das Schlüsselwort ELSE
und der
dazugehörende Befehl können auf derselben Zeile oder getrennt durch eine beliebige
Anzahl von leeren Zeilen geschrieben werden. Wiederum spielen Groß-/Kleinschreibung oder
Anzahl der Leerstellen keine Rolle:
IF alter < 20 then
say "Sie sind relativ jung."
ELSE
say "richtig jung sind Sie auch nicht mehr."
...zum Beispiel. Oder auch - um ein letztes Beispiel zu geben - hier die Variante, die sich am besten lesen und verstehen läßt:
IF alter < 20 then
say "Sie sind relativ jung."
ELSE
say "richtig jung sind Sie auch nicht mehr."
Daraus kann man sehr schön die zwei Grundregeln erkennen:
"IF"
, die geprüfte Bedingung
("alter < 20"
) und das "THEN"
Schlüsselwort stehen in derselben Zeile."ELSE"
befindet sich in einer anderen Zeile
als der zum ersten Zweig gehörende Befehl.Wenn Sie mehrzeilige Befehle in REXXtry ausprobieren wollen, müssen Sie Vorsicht walten
lassen. REXXtry ist lediglich eine vorgeschaltete Ein-Ausgabe-Umgebung, die jede eingegebene
Zeile sofort an REXX übergibt, das diese dann komplett verarbeitet. Das bedeutet im
Beispiel einer mehrzeiligen IF
-Anweisung, daß ELSE
und "sein
Rest" nicht mehr in Zusammenhang mit der vorherigen Zeile gesehen werden und das Ganze mit
einem Syntaxfehler ("unvollständige IF/THEN/ELSE-Struktur") abgewiesen wird.
Fassen wir zusammen, was wir bis jetzt über die Syntax von IF
gelernt
haben:
IF <Bedingung erfüllt> THEN
<Befehl-1>
ELSE
<Befehl-2>
Okay, machen wir weiter. Es gibt noch eine Besonderheit zu IF
in REXX, die man
kennen wollte - speziell, wenn man bereits mit anderen höheren Programmiersprachen wie Basic
oder COBOL gearbeitet hat: REXX gestattet lediglich eine Anweisung pro Zweig -
außer, man verwendet explizit die Befehlswörter DO
und END
,
um einen Block mehrerer Anweisungen darin einzuschließen. Das bedeutet, daß als
Erweiterung zur obigen Syntax anstelle von <Befehl-1>
und/oder
<Befehl-2>
auch folgende Struktur zulässig ist:
do
Befehl-2
Befehl-3
...
Befehl-n
end
DO
und END
dienen also hierbei dazu, mehrere Anweisungen als einen einzigen Block zu
kennzeichnen, damit "der Parser es kapiert".
Da die DO...END
-Blöcke genau wie ein einzelner Befehl angesehen werden (aus
Sicht des Parsers), kann man also einzelne Befehle oder Blöcke jeweils pro Zweig ganz nach
Bedürfnis innerhalb eines IF
"mischen":
IF <Bedingung erfüllt> THEN
DO
<
Befehl
-1>
<
Befehl
-2>
END
ELSE
<
Befehl
-3>
oder "das volle Programm":
IF <Bedingung erfüllt> THEN
DO
<
Befehl
-1>
<
Befehl
-2>
END
ELSE
DO
<
Befehl
-3>
<
Befehl
-4>
END
Es steht Ihnen frei, das "DO"
und den ersten Befehl des Blocks in
derselben Zeile anzugeben - auch in derselben Zeile wie das IF
selbst.
Voraussetzung für's Gelingen (also, daß der Parser es nicht wieder
mißversteht) ist, daß Sie auch hier ein Semikolon benutzen, um
"DO"
und den ersten Befehl voneinander zu trennen. Gut, machen wir's
kurz. Alle folgenden Beispiele haben die gleiche Bedeutung:
a.)
IF <Bedingung erfüllt> THEN
DO
<
Befehl
-1>
....
END
b.)
IF <Bedingung erfüllt> THEN DO
<
Befehl
-1>
....
END
c.)
IF <Bedingung erfüllt> THEN DO; <Befehl
-1>
....
END
d.)
IF <Bedingung erfüllt> THEN
DO; <
Befehl
-1>
....
END
Uff! Ich weiß, es wird kompliziert... sind Sie noch da? ;-)
Um möglichst unkompliziert durch dieses Thema zu kommen, merken Sie sich einfach das
erste Beispiel als Referenz: "THEN
, DO
und
<
Befehl-
>
stehen jeweils in einer eigenen
Zeile. Das sieht nicht nur besser aus, sondern liest und versteht sich einfacher!
Um Sie vollends zu verwirren, kommen wir nun zu der Tatsache, daß ein mit
DO/END
eingeschlossener Anweisungsblock im Zweig eines IF
selbstverständlich selber auch weitere IF
s enthalten kann. ;-)
Gut, es mag auf Anhieb verwirrend sein, aber hey: Im Prinzip ist das wie eine Zwiebel zu sehen,
bei der jede Schicht ein IF darstellt. Und "pro Schicht" gesehen sind die IFs doch ganz
easy und keine Zauberei.
Stellen Sie sich einfach vor, daß Sie wieder in diesem Korridor stehen und durch eine der Türen gehen. Natürlich könnten Sie dann erneut sofort vor weiteren Türen stehen. Und das bezeichnen wir dann als "verschachtelte IF-Struktur". Aber wie gesagt - im Prinzip handelt es sich um nichts anderes als wieder und wieder das, was wir oben gelernt haben. Beispiel gefällig? Hier isses:
say "Bitte Namen eingeben (und die Eingabetaste betätigen)..."
parse pull name
say "Hallo" name
buchstaben = length(strip(name))
say "Boah - Ihr Name besteht aus" buchstaben "Buchstaben."
if buchstaben < 5 then
if buchstaben < 4 then
do
call beep 500,100
say "...und das ist echt kurz, Mann!"
end
else
say "...und das ist ziemlich kurz."else
say "...und das ist schon eher lang."
Nun gut - vom Verwendungszweck her ist das ein echt doofes Programm, aber es soll ja
auch nur das Prinzip von zwei "verschachtelten" IF
s verdeutlichen: Das
erste IF
(das "äußere") besteht aus zwei Zweigen (wie immer),
wobei jedoch der erste Zweig wiederum ein IF
(das "innere") enthält.
Und dieses innere IF
verwendet übrigens einen
DO/END
-Anweisungsblock im eigenen ersten Zweig.
Kommen wir nun zu meiner ominösen Formulierung "...vor zwei oder mehr
Türen":
Die IF
-Anweisung verwendet eine Bedingung, die geprüft wird. Um sicher zu
stellen, daß Sie den Unterschied merken, fange ich es noch mal so an: Die Bedingung - egal
wie komplex sie auch sein mag - ist entweder WAHR oder NICHT WAHR . Ein IF
erzeugt somit am Ende des Korridors grundsätzlich nur zwei Türen. Wenn wir vom obigen
Beispiel ausgehen und jetzt beispielsweise noch zwischen "ziemlich langen" und
"echt langen" Namen unterscheiden wollen, müßten wir also den zweiten Zweig des
äußeren IF
"aufbohren" und um ein weiteres IF
ergänzen... und früher oder später wird das Ganze so komplex und
unübersichtlich, daß die Wahrscheinlichkeit sich einschleichender Fehler steigt.
Natürlich wäre das keine "falsche" Art der Programmierung, aber vielleicht
nicht mehr die "beste". Lassen Sie uns mal nachschauen, ob es nicht andere Mittel gibt,
da etwas zu machen. Eigentlich wollen wir ja nun nicht mehr prüfen, ob eine einzelne
Bedingung zutrifft oder nicht. Vielmehr wollen wir ja jetzt auf verschiedene
"Zustände" unterschiedlich reagieren. In unserem (dümmlichen) Beispiel geht
es darum, unterschiedliche Längen von Namen zu erkennen. Wir können also nun eine
umständliche Verschachtelung von etlichen IFs verwenden, oder einfach REXXs
"select"-Anweisung:
say "Bitte Namen eingeben (und die Eingabetaste betätigen)..."
parse pull name
say "Hallo" name
buchstaben = length(strip(name))
say "Boah - Ihr Name besteht aus" buchstaben "Buchstaben."
select
when buchstaben < 4 then
say "...und das ist echt kurz, Mann!"
when buchstaben < 6 then
say "...und das ist ziemlich kurz."
when buchstaben < 9 then
say "...und das ist ziemlich lang."
otherwise
say "...und das ist echt lang, Mann!"
end
Jawoll! Na, das sieht doch genau so aus, wie das, wonach wir gesucht haben, aber genießen
Sie select
mit Vorsicht. Die eigentliche Verarbeitung hinter diesem Befehl
läuft nämlich so ab, daß jede der einzelnen Bedingungen (von oben nach unten)
abgeprüft wird und die erste zutreffende Bedingung verarbeitet wird. Als einzige. Das
bedeutet, daß Sie sich dieses Prinzip verdeutlichen müssen, wenn Sie die Reihenfolge
der Bedingungen festlegen... so sieht das folgende Beispiel auf den ersten Blick ganz gut
aus, aber es birgt einen kleinen logischen Lapsus:
select
when buchstaben > 3 then
say "...und das ist echt kurz, Mann!"
when
buchstaben
> 5 then
say "...und das ist ziemlich kurz."
when
buchstaben
> 7 then
say "...und das ist eher lang."
otherwise
say "...und das ist echt lang, Mann!"
end
das Problem ist nämlich, daß wenn die Variable buchstaben
beispielsweise den Wert 6 enthält, auch schon die erste Bedingung (> 3) zutrifft.
Natürlich trifft auch die zweite Bedingung zu (> 5) aber dazu kommt REXX gar nicht mehr,
weil wie gesagt die erste bereits zutraf und verarbeitet wurde. Das Schlüsselwort
otherwise
dient übrigens zur Behandlung aller Fälle, die nicht bereits
durch eine der vorherigen Bedingungen abgefangen wurden - quasi eine Art von "ELSE"
für das select, wenn Sie so wollen.
Noch eine Spezialität von select
in REXX ist, daß es anders strukturiert
ist als seine äquivalenten Gegenstücke in anderen Programmiersprachen wie z.B.
"evaluate" in COBOL oder "select case" in Basic. Die sind zwar wirklich sehr
ähnlich, allerdings verwenden sie unterschiedliche Ausprägungen zu einer einzigen
Bedingung. Das bedeutet, die zu prüfende Bedingung wird einmal (zu Beginn der
Befehlssyntax) definiert und die einzelnen Zweige behandeln unterschiedliche Ergebnisse. Ein
Beispiel aus COBOL:
Gewiefte COBOL-Programmierer hätten zwar eher ein paar geeignete 88er-Stufen zur Variable "BUCHSTABEN" angelegt und diese dann auf TRUE abgefragt, aber das ist eine andere Geschichte... ;)EVALUATE BUCHSTABEN
CASE IS < 4
DISPLAY "...und das ist echt kurz."
CASE IS < 6
DISPLAY "...und das ist ziemlich kurz."
...
END-EVALUATE.
Der Unterschied zur REXX-Variante ist nun, daß hier die zu prüfende Bedingung bei jedem Zweig neu definiert wird. Somit können die Zweige auch dazu verwendet werden, total verschiedene Sachen zu prüfen - ob das nun Sinn macht oder nicht. Normalerweise wird man zwischen unterschiedlichen Ausprägungen derselben Abfrage unterscheiden wollen (wie z.B. dem möglichen Inhalt einer Variablen) und nicht etwa Sachen einbeziehen, die gar keinen logischen Zusammenhang besitzen. Es kann natürlich Situationen geben, wo dies angebracht wäre, aber solche Klamotten sind nicht gerade auf den ersten Blick zu verstehen, wie
select
when alter > 55 then
say "Als Programmierer müssten Sie ja noch Lochkarten kennen, oder?"
when name = "Peter"
say "Sie schon wieder!"
when date('S') = "20040101" then
say "Frohes neues Jahr!"
end
Das wäre ein klassisches Beispiel eines "WasSollDasDenn?!"-Konstrukts, da es
einige Fragen aufwirft. Zum Beispiel, wofür zum Teufel das Ding gut sein soll. Solche
Kombinationen sind im Normalfall Quatsch, denn selbstverständlich könnten mehrere oder
auch alle Bedingungen zutreffen - doch nur die erste würde dann verarbeitet. Wie Sie
vielleicht noch wissen, können Sie nur durch eine der Türen am Ende des Korridors
"gleichzeitig" gehen...
Was also soll denn geschehen, wenn "Peter" eingegeben wurde, der Typ 57 Jahre alt
ist und dieses Programm am 1. Januar 2004 läuft?
Jede der abgefragten Bedingungen trifft zu, aber nur die erste wird verwendet... um also in der
Lage zu sein, Programme mit einem relativ vorhersehbaren Verhalten zu schreiben, sollte man
solche Sachen vermeiden. In diesen Fällen sind andere Codierungen wohl besser geeignet - wie
mehrere aufeinander folgende und/oder verschachtelte IF
s zum Beispiel.
Zusammenfassend kann man also sagen, daß SELECT
intern wie "aneinander
geklebte" IFs funktioniert. Das ist auch der Grund, warum die zu prüfende Bedingung bei
jedem Zweig wieder neu angegeben wird. Denken Sie bei der Verwendung daran, sonst erschaffen Sie
sich einen wunden Punkt; bestens geeignet zum Einbauen von logischen Fehlern.
Zu guter Letzt hier noch eine Zusammenstellung der syntaktischen Eigenschaften des
SELECT
Befehls (anstelle eines weiteren öden Schemas):
SELECT
muss durch ein
"END"
beendet werden.SELECT
selbst kann in derselben Zeile stehen wie die
erste komplette "WHEN
/Bedingung/THEN
"-Anweisung oder
alleine.WHEN,
die Bedingung und das Schlüsselwort
THEN
müssen zusammen in derselben Zeile stehen (also wie
IF/.../THEN
).<Befehl>
kann in derselben Zeile stehen wie die
WHEN/.../THEN
-Anweisung.<Befehl>
kann auch ein Anweisungsblock mit DO...END
sein (auch wie beim IF
-Befehl).ELSE
in den Zweigen.OTHERWISE
(zusammen mit dem zugehörigen
<Befehl>
oder DO...END
-Anweisungsblock) ist optional!Zum DO/.../END
Anweisungsblock gibt es noch was zu sagen: Wenn der verwendet
wird, kann das Schlüsselwort DO
entweder alleine in einer Zeile stehen oder
zusammen mit dem ersten Befehl des Blocks - dann aber mit einem Semikolon dazwischen. Das gilt
auch für den Fall, daß DO
in derselben Zeile wie das
WHEN/.../THEN
steht. Folglich sind alle folgenden Codeteile gültig und
gleichwertig:
a.)
SELECT
WHEN alter > 55 then
DO
call beep 100,500
say "Sie sind älter als ich."
END
WHEN...
b.)
SELECT
WHEN alter > 55 then DO
call beep 100,500
say "Sie sind älter als ich."
END
WHEN ...
c.)
SELECT WHEN alter > 55 then DO; call beep 100,500
say "Sie sind älter als ich."
END
WHEN ...
d.)
SELECT WHEN alter > 55 then
DO; call beep 100,500
say "Sie sind älter als ich."
END
WHEN ...
Wiederum ist es hier die erste Notationsvariante (a.), der Sie den Vorzug geben sollten: Kein Ärger mit Semikolons, bessere Lesbarkeit, nun ja... es hängt letztlich von Ihrem "Geschmack" in Sachen selbstdokumentierendem Quellcode ab. Der Parser prüft Ihren "Kram" nur nach bestimmten Regeln und schert sich nicht um solche Sachen wie Einrückungen oder ähnliches - so etwas interessiert nur Menschen... ;)
Um zu verhindern, daß ich diesen Beitrag mit "nichts
nützlichem" beende, lassen Sie mich Ihnen lieber noch ein "nützliches
Nichts" vorstellen ;-) - den Befehl NOP
. Den kennen Sie vielleicht aus Assembler
und ja - das REXX-Gegenstück macht genau dasselbe: Nichts. Ist das nicht lustig? Ein
eigenes, spezielles Kommando, das verwendet wird, um NICHTS zu tun. Vielleicht fragen Sie
sich jetzt, "wofür zum Teufel man so was braucht?" und die simple Antwort ist:
Für nichts. ;-) Es dient nicht dazu, irgendetwas zu "machen" sondern lediglich zum
Auffüllen von "Lücken in sichtbar gemachter Logik".
NOP
ist immer dann ziemlich praktisch, wenn die verschachtelten bedingten
Verzweigungen plötzlich an einer Stelle ankommen, die einen gar nicht interessiert, weil man
nämlich nur die "anderen" Zweige abfangen will.
Wie wir irgendwo oben bereits erwähnten, ist das ELSE
in Befehl IF
optional; es steht Ihnen also frei, es zu verwenden oder nicht... auf der anderen Seite - speziell
in Zusammenhang mit komplexen verschachtelten Abfragen - sieht der Quellcode einfach
"klarer" aus, wenn jedes IF
sein ELSE
hat - auch wenn bei
diesem ELSE
nichts gemacht wird. Ein Beispiel:
if alter > 37 then
say "Sie sind älter als ich."
Bei Verwendung von NOP
würde das dann so aussehen:
if alter > 37 then
say "Sie sind älter als ich."
else
NOP
Wenn nun also jemand anders mit Ihrem Quellcode arbeiten muß (oder Sie selbst nach ein paar
Monaten wieder hineinschauen), gibt es bei dieser Abfrage keinen Klärungsbedarf, ob das ELSE
aus Faulheit weggelassen oder sogar fehlerbedingt vergessen wurde... es ist stattdessen ziemlich
klar: ELSE NOP
sagt wohl eindeutig aus, daß wirklich NICHTS gemacht werden
soll, wenn die Bedingung nicht erfüllt ist. Selbstverständlich kann
NOP
auch in den Zweigen von SELECT
verwendet werden,
beispielsweise in...
Select
when a > b then
say "Es besteht eine Differenz von" a - b
when a < b then
say "Es besteht eine Differenz von" b - a
otherwise
nop
end
Dieser Code ist selbsterklärend, es bleiben keine Fragen offen. Einige
Programmiersprachen zwingen Sie dazu, zweimal zu überlegen, wie man die einzelnen
Bedingungsabfragen umsetzt, um das gegebene Ziel zu erreichen. Hat man jedoch ein
NOP
zur Hand, braucht man sich den Kopf nicht ganz so doll zu zerbrechen... ;-)
Genug Code-Arbeit für heute! Wenn Sie es bis hier unten geschafft haben, ohne daß
der Kopf raucht, ja... dann bin ich stolz auf Sie! ;-)
Nächsten Monat besprechen wir die dritte Art von Programmstrukturen - Iterationen (oder
"Schleifen", wenn Sie so wollen) - und wie man die in REXX bewerkstelligt.
Daten und Quellen:
|
[Artikelverzeichnis]
editor@os2voice.org
[Vorherige Seite] [Inhaltsverzeichnis] [Nächste Seite]
VOICE Homepage: http://de.os2voice.org