Liebe Alle,
oops, meine Antwort erging nur an Jana, hier an alle.
Mit freundlichem Gruß
Rony G. Flatscher
-------- Forwarded Message -------- Subject: Erklärung ... (Re: [Wu_bp_2022w] G03 T03 Date: Fri, 4 Nov 2022 18:02:47 +0100 From: Rony G. Flatscher Rony.Flatscher@wu.ac.at To: Jana Korunovska jana.korunovska@wu.ac.at
On 03.11.2022 15:32, Jana Korunovska wrote:
Ups, ich war ein bisschen übereifrig, dies ist der richtige E-Mail-Betreff.
Und eine Frage: weiß jemand, warum wir bei unserer ersten Übung den Befehl RAISE USER something_raised in der vorletzten Zeile nicht sehen?
Ja! ;)
Hier eine Variante des Programms, danach die Erklärung:
CALL ON ANY /* intercept anything that is not caught explicitly */ CALL ON USER GRUNDSTUFE /* intercept a user exception GRUNDSTUFE*/ CALL ON USER UNTERSTUFE /* intercept a user exception UNTERSTUFE */ CALL ON USER OBERSTUFE /* intercept a user exception OBERSTUFE */ CALL stufe 1 CALL stufe 2 CALL stufe "oberstufe" /* <- this is line # 7 */ CALL stufe 4 /* <- this is line # 8 */ CALL stufe 3 CALL stufe "grundstufe" /* <- this is line # 10 */ CALL stufe "uni" /* <- this is line # 11 */ EXIT 0 ANY : SAY "in Linie:" SIGL "Exception:" CONDITION("C"); RETURN grundstufe: SAY "[caught exception 'GRUNDSTUFE' ]"; RETURN unterstufe: SAY "[ caught exception 'UNTERSTUFE']"; RETURN oberstufe:SAY "[caught exception 'OBERSTUFE' ]"; RETURN ::ROUTINE stufe PARSE ARG stufe SAY ':STUFE:' STUFE *say "-> stufe>3:" stufe ">" 3":" (stufe > 3)* IF STUFE =1 | stufe = "grundstufe" THEN RAISE USER grundstufe; if stufe = 2 | stufe = "unterstufe" then raise user unterstufe; if stufe =3 | stufe = "oberstufe" then raise user oberstufe ELSE IF stufe > 3 THEN RAISE USER irrelevant ELSE SAY '--> checked o.k.'
Hier die Ausgaben:
REXXout>:STUFE: 1 REXXout>*-> stufe>3: 1 > 3: 0* REXXout>[caught exception 'GRUNDSTUFE' ] REXXout>:STUFE: 2 REXXout>*-> stufe>3: 2 > 3: 0* REXXout>[ caught exception 'UNTERSTUFE'] REXXout>:STUFE: oberstufe REXXout>*-> stufe>3: oberstufe > 3: 1* REXXout>[caught exception 'OBERSTUFE' ] REXXout>:STUFE: 4 REXXout>*-> stufe>3: 4 > 3: 1* REXXout>in Linie: 10 Exception: USER IRRELEVANT REXXout>:STUFE: 3 REXXout>*-> stufe>3: 3 > 3: 0* REXXout>[caught exception 'OBERSTUFE' ] REXXout>:STUFE: grundstufe REXXout>*-> stufe>3: grundstufe > 3: 1* REXXout>[caught exception 'GRUNDSTUFE' ] REXXout>:STUFE: uni REXXout>*-> stufe>3: uni > 3: 1* REXXout>in Linie: 13 Exception: USER IRRELEVANT
Hier die Erklärung:
Nachdem in Rexx alles Zeichenketten sind, wird Zeichen für Zeichen verglichen (führende und nachfolgende Leerzeichen werden normalerweise ignoriert). Die Position eines Zeichens in der Zeichensatztabelle [1],[2] bestimmt, ob ein Zeichen kleiner oder größer als ein anderes ist. Ein Zeichen ist dann kleiner als ein anderes, wenn dessen Position in der Zeichensatztabelle kleiner (niedriger ist), sonst ist es entweder gleich (wenn es mit dem gleichen Zeichen verglichen wird) oder größer.
Eine "Zeichensatztabelle" besteht üblicherweise aus 256 Zeichen, deren Positionen von 0 bis 255 nummeriert sind. Die ersten 128 Zeichen (in den Positionen von 0 bis 127) sind der "ASCII"-Zeichensatz [3] und ist in allen Zeichensatztabellen gleich belegt. Die 128 weiteren Zeichen (von Position 128 bis 255) sind je nach Zeichensatztabelle unterschiedlich mit Zeichen belegt.
In unseren Breiten wird die Zeichensatztabelle 850, "Western Europe", [4] (oder in Windows, z.B. in MS Word die Zeichensatztabelle 1252, "Latin 1", [5]) verwendet, die die häufigst gebrauchten westeuropäischen Zeichen in den Positionen von 128 bis 255 beinhaltet, so z.B. unsere deutschen Sonderzeichen und das scharfe s.
Die folgenden Vergleiche ergeben "1" (wahr, .true):
**-> *stufe>3: grundstufe > 3: 1 **-> stufe>3: uni > 3: 1*
Also "grundstufe" ist größer als "3", "uni" ist größer als "3" !
Wenn man jetzt die Positionen von "g" (erster Buchstabe in "grundstufe") und "3" in der Zeichensatztabelle sucht ist "g" auf Position 103 (dezimal), "3" auf Position 51 (dezimal). 103 ist tatsächlich größer 51, daher ist das Ergebnis des Vergleichs "1" (wahr, .true)!
Bei "uni" suchen wir den ersten Buchstaben "u", der auf Position 117 (dezimal) liegt. 117 ist auch hier größer als 51, daher ist das Ergebnis des Vergleichs "1" (wahr, .true)!
Um in Eurem Beispiel "USER SOMETHING_RAISED" aufzurufen ist es notwendig, die Bezeichnung mit einem Zeichen beginnen zu lassen, das vor der Position 51 (die Ziffer "3") liegt, z.B. die Raute ("#" auf Position 35). Eine mögliche Bezeichnung wäre dann z.B. "#uni". Wenn Ihr dann folgende Anweisung einfügt:
CALL stufe "#uni"
Dann wird die Ausgabe des Programms wie folgt sich ändern:
... cut ... REXXout>:STUFE: #uni REXXout>->*stufe>3: #uni > 3: 0* REXXout>--> checked o.k. REXXout>*in Linie: 12 Exception: USER SOMETHING_RAISED*
Einfach im eigenen Code ausprobieren!
Zeichensatztabellen werden uns wieder begegnen, daher zahlt es sich aus, sich ein wenig damit auseinanderzusetzen. Die beigefügten deutschen und englischen Links liefern die entsprechenden Hintergrundinformationen. Eine schöne Wochenendlektüre! ;)
HTH
---rony
[1] https://de.wikipedia.org/wiki/Zeichensatztabelle [2] https://en.wikipedia.org/wiki/Code_page [3] https://en.wikipedia.org/wiki/ASCII [4] https://de.wikipedia.org/wiki/Codepage_850 [5] https://en.wikipedia.org/wiki/Code_page_850 [6] https://de.wikipedia.org/wiki/Windows-1252 [7] https://en.wikipedia.org/wiki/Windows-1252