Wissenswertes über einen Programmiersprachenurahn

COBOL – Die Sprache der Buchhalter
Kommentare

Laut bösen Zungen entstand COBOL – die Bezeichnung steht für Common Business-Oriented Language – im Rahmen der wachsenden Verbreitung von Mikrocomputersystemen. Unternehmen suchten händeringend nach Programmierern, die in viel zu geringer Menge zur Verfügung standen.

Die US-Regierung begegnete dem Problem durch die Entwicklung einer neuen Programmiersprache, die ob ihres einfachen Aufbaus auch für Nichttechniker geeignet sein sollte. Im Laufe der Jahre erreichte COBOL so eine immense Verbreitung im Bereich Banken und Versicherungen. COBOL wurde mehrfach überarbeitet. Neben COBOL 72 und COBOL 85 gibt es mit dem 2002 erschienenen Object-Oriented COBOL sogar eine objektorientierte Variante der Sprache. Da sie nur vergleichsweise wenig Verbreitung erreicht hat, wollen wir sie in diesem Artikel nicht weiter behandeln.

Für Entwickler ist COBOL nicht nur aus historischen Gründen interessant. Die im Laufe der Jahre erstellten Systeme laufen nach wie vor, benötigen aber immer wieder Anpassungen. Da Universitäten und höhere technische Lehranstalten schon lange keine neuen COBOL-Programmierer mehr trainieren, steht einem mehr oder weniger konstant großen Markt eine immer kleinere Menge von Lieferanten zur Verfügung.

Den Quellcode zu diesem Artikel finden Sie auf der Magazinseite des Entwickler Magazins 5.15

Diese Situation führt zu den aus dem Wirtschaftslehrbuch bekannten Phänomenen. Dem Autor ist eine Handelsschulabsolventin bekannt, die ihre Einnahmen durch Anbieten von COBOL-Konsultationsdienstleistungen in astronomische Höhen katapultieren konnte. Ob der kleinen Größe des Gesamtmarkts kommunizieren Auftraggeber zudem untereinander: Wer bei einer Wartung erfolgreich mitgewirkt hat, zieht Folgeaufträge geradezu magnetisch an.

COBOL herbei

Für die folgenden Schritte wollen wir uns auf eine unter Ubuntu verfügbare, quelloffene Implementierung der Programmiersprache COBOL beschränken. Sie lässt sich durch Eingabe des folgenden Befehls auf Ihre Maschine herunterladen:

tamhan@tamhan-elitebook:~$ sudo apt-get install open-cobol 
[sudo] password for tamhan: 
. . .

Im nächsten Schritt folgt die Erstellung eines Hello-World-Programms. COBOL-Code liegt normalerweise in Dateien mit der Endung .cbl – es gibt auch Unternehmen, die stattdessen auf die generische Dateiendung .src setzen. Den Inhalt von HelloWorld.cbl zeigt Listing 1.

IDENTIFICATION DIVISION. 
PROGRAM-ID. HELLOSUS. 
PROCEDURE DIVISION. 
DISPLAY 'Nichts wie los!'. 
STOP RUN.

Wer eine .cbl-Datei mit dem auf den meisten Unix-Systemen vorinstallierten gedit öffnet, wird vom Editor mit grundlegendem Syntax-Highlighting versorgt. Der genaue Code ist für uns erst im nächsten Abschnitt relevant – im Moment genügt die Eingabe der folgenden Kommandos, die die Programmausführung anwerfen:

tamhan@tamhan-elitebook:~/SUSCobol$ cobc -free -x -o helloworldexe helloworld.cbl 
tamhan@tamhan-elitebook:~/SUSCobol$ ./helloworldexe 
Nichts wie los! 

Sprechen Sie Lochkarte?

COBOL-Programme residieren oft auf Lochkarten. Da die Entwicklung von Parsern zum damaligen Zeitpunkt nur wenig fortgeschritten war, führte die Sprachspezifikation eine Gruppe von Syntaxregeln zur Vereinfachung der Analyse ein. Die bis COBOL 2002 verpflichtende Formatierungskonvention schrieb eine bestimmte Menge von Leerzeichen vor, die die einzelnen Module voneinander abtrennen. Der Autor eines Parsers konnte so durch Zählung der Leerzeichen Rückschlüsse über die Art des vorliegenden Kommandos ziehen.

Da heutige Parser mit beliebig komplexen Grammatiken zurechtkommen, ist die Nutzung der beschreibenden Leerzeichen heute nicht mehr notwendig. Im durch Übergabe von -free aktivierbaren Free Mode parst der Compiler „frei Schnauze“. Weitaus wichtiger ist die in Abbildung 1 gezeigte Programmstruktur, die sich in unserem Beispielcode – wenn auch nur teilweise – abgebildet wiederfindet.

hanna_cobol_1

Abb. 1: COBOL ist vergleichsweise komplex aufgebaut

Divisionen stellen den obersten Teil der COBOL-Ontologie dar. Im als „identification division“ bezeichneten Block finden sich Informationen über die Art des vorliegenden Programms. Der abzuarbeitende Code liegt in der „procedure division“. Variablen werden in der „data division“ deklariert, die „environment division“ enthält weitere Informationen über die vom Programm verwendeten Eingabe- und Ausgabedateien.

Die darunterliegenden Sections und Paragraphs erlauben die weitere Unterteilung des vorliegenden Codes. Sentences, Statements und Characters finden sich nur in der „procedure division“. Ein Sentence ist eine Kombination von mehreren Kommandos, die – Ähnlichkeiten zur englischen Sprache sind rein zufällig – durch einen Punkt abgeschlossen werden müssen.

Etwas zusätzliche Logik

Als nächste Aufgabe wollen wir uns der Realisierung des FizzBuzz-Tests zuwenden. Das in angelsächsischen Kreisen als Fingerübung für angehende Programmierer weit verbreitete Programmbeispiel bietet uns einige Möglichkeiten zum Experimentieren. Akt Numero 1 ist die Realisierung einer For-Schleife. Dazu erstellen wir eine neue Datei namens fizzbuzz.cbl, deren Grundaufbau Listing 2 darstellt.

IDENTIFICATION DIVISION. 
PROGRAM-ID. FIZZBUZZ. 
 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
01 COUNTVAR PIC 999 VALUE 0. 

PROCEDURE DIVISION. 
PERFORM COUNTRUN 25 TIMES. 
STOP RUN. 

COUNTRUN. 
DISPLAY COUNTVAR. 
ADD 1 TO COUNTVAR.

An dieser Stelle finden sich drei signifikante Änderungen. Als Erstes haben wir eine neue Division eingeführt: In der DATA DIVISION werden die vom Programm benötigten Variablen angelegt. Als Entgegenkommen an nicht IT-affine Personen kennt COBOL keine klassischen Datentypen – die Variablen werden stattdessen mit einem als Data Picture bezeichneten Attribut versehen, das die Art der zu speichernden Informationen und die Art der gewünschten Darstellung am Bildschirm zusammenfasst. Mit dem optionalen Value-Attribut lässt sich die Erstinitialisierung problemlos bewerkstelligen.

In der „procedure division“ finden wir das COBOL-Äquivalent zur For-Schleife. PERFORM X Y TIMES führt die als X übergebene „Division“ Y-mal aus. In unserem Fall wird das „Unterprogramm“ COUNTRUN 25 Mal abgearbeitet. Nach der durch COUNTRUN. beginnenden Deklaration findet sich der eigentliche Code, der den aktuellen Inhalt von COUNTVAR inkrementiert und ausgibt. Damit können wir COUNTRUN um die eigentliche FizzBuzz-Logik erweitern, die aus einer Gruppe von Selektionen besteht. Ersetzen Sie den Korpus durch das Snippet in Listing 3.

COUNTRUN. 
IF COUNTTHREE = 3 
THEN IF COUNTFIVE = 5 
  THEN DISPLAY "FizzBuzz" 
  COMPUTE COUNTFIVE = 0 
  ELSE DISPLAY "Fizz" 
  END-IF 
  COMPUTE COUNTTHREE = 0 
ELSE IF COUNTFIVE = 5 
THEN DISPLAY "Buzz" 
    COMPUTE COUNTFIVE = 0 
ELSE 
    DISPLAY COUNTVAR 
END-IF 
END-IF 
ADD 1 TO COUNTTHREE 
ADD 1 TO COUNTFIVE 
ADD 1 TO COUNTVAR.

Die von Takano Mitsuhiro vorgeschlagene – und hier mit minimalen Änderungen übernommene – Lösung des FizzBuzz-Problems unterscheidet sich von klassischen Implementierungen durch das Fehlen des Modulo-Operators. Der Japaner setzt stattdessen auf zwei weitere Zählvariable, die in der DATA DIVISION zu Hause sind.

COBOL zeichnet sich durch eine etwas eigenwillige Syntax der If-Selektion aus:

 
IF condition-1  THEN
  statements
[ELSE statements ]
[END-IF].

Selektionen arbeiten zweiwertig: Der mit THEN terminierte Teil wird vom Kriterium gesteuert, während ELSE im Nichtfall zur Ausführung kommt. Mehrstufige If-Selektionen werden durch klassische Verschachtelung realisiert. Es spricht nichts dagegen, den Else-Teil mit einem weiteren If auszustatten. Damit ist die Arbeit an diesem Programm abgeschlossen. Kompilieren Sie es, um sich an der in Abbildung 2 gezeigten Ausgabe zu erfreuen.

Abb. 2: Falls Ihr präsumtiver Auftraggeber im Bewerbungsgespräch auf FizzBuzz setzt, sind Sie nun bestens vorbereitet

Abb. 2: Falls Ihr präsumtiver Auftraggeber im Bewerbungsgespräch auf FizzBuzz setzt, sind Sie nun bestens vorbereitet

Aus didaktischen Gründen sei in Listing 4 noch eine zweite FizzBuzz-Version vorgestellt, die ohne die zusätzlichen Variablen auskommt.

PROCEDURE DIVISION. 
PERFORM 25 TIMES 
IF FUNCTION MOD(COUNTVAR, 3) = 0  AND FUNCTION MOD(COUNTVAR, 5) = 0  THEN
DISPLAY 'FIZZBUZZ' 
ELSE 
IF FUNCTION MOD(COUNTVAR, 3) = 0 THEN
DISPLAY 'FIZZ' 
ELSE IF FUNCTION MOD(COUNTVAR, 5) = 0 THEN DISPLAY 'BUZZ'
ELSE DISPLAY COUNTVAR
END-IF 
END-IF 
END-IF
ADD 1 TO COUNTVAR
END-PERFORM.
STOP RUN.

Neben der Nutzung des für Funktionsaufrufe zuständigen Verbs FUNCTION findet sich hier eine alternative Variante der Perform-Schleife, die ohne Einrichtung eines Paragraphs auskommt. In der Literatur findet sich keine goldene Regel, ab welchem Komplexitätsgrad die Auslagerung in ein Unterprogramm sinnvoll ist. Richten Sie sich in Wartungsprojekten am besten nach dem schon vorhandenen Code.

Das EVA-Prinzip ist im IT-Bereich weit verbreitet: Prozessrechner sammeln Daten ein, verarbeiten sie weiter und geben danach die Resultate aus. Unsere COBOL-Programme sind im Moment nicht zur Interaktivität befähigt, sie verarbeiten lediglich die angelieferten Daten.

Generationen von IT-Fachautoren haben verzweifelt nach Beispielen gesucht, die primitive Einleseoperationen auf eine geschäftlich sinnvolle Art und Weise präsentieren. Wir wollen an dieser Stelle einen primitiven Widerstandsrechner realisieren, der das ohmsche Gesetz implementiert. Sein Code findet sich in Listing 5.

IDENTIFICATION DIVISION. 
PROGRAM-ID. OHMCALC. 

DATA DIVISION. 
WORKING-STORAGE SECTION. 
01 R PIC X(9). 
01 U PIC X(9). 
01 I PIC X(9). 
01 CR PIC 9(9). 
. . .
01 LR PIC 9(5). 
. . .
01 ACCU PIC 9(5). 

PROCEDURE DIVISION. 
DISPLAY 'R erbeten oder NULL' 
ACCEPT R 
DISPLAY 'U erbeten oder NULL' 
ACCEPT U 
. . .

Als „ersten Akt“ müssen wir die vom Benutzer einzugebenden Daten entgegennehmen. Dies erfolgt durch einen Aufruf der ACCEPT-Funktion, die die eingelesenen Zeichenketten direkt – und ohne Verifikation – in die angewiesenen Variablen schreibt (Listing 6).

INSPECT R TALLYING LR FOR TRAILING ' '
COMPUTE LR = 9 - LR 
INSPECT U TALLYING LU FOR TRAILING ' '
COMPUTE LU = 9 - LU 
INSPECT I TALLYING LI FOR TRAILING ' '
COMPUTE LI = 9 - LI 

COBOL kennt keine terminierten Strings. Die Ermittlung der Länge einer Zeichenkette lässt sich behelfsmäßig durch das Zählen der am Ende befindlichen Spaces ermitteln – die tatsächliche Länge ist dann die Länge des Felds abzüglich der Leerzeichen. Zeichenketten sind in COBOL nicht für Berechnungen zugelassen. Aus diesem Grund verschieben wir die Daten per Move-Kommando in berechnungsgeeignete Variablen:

MOVE R TO CR 
MOVE U TO CU 
MOVE I TO CI 

Damit fehlt uns nur noch die eigentliche Berechnung neben der Ausgabe der erzeugten Werte. COBOL-Parser werden durch das COMPUTE-Schlüsselwort darüber informiert (Listing 7).

IF LR = 0 THEN 
COMPUTE ACCU = CU / CI 
END-IF 
IF LU = 0 THEN 
COMPUTE ACCU = CR * CI 
END-IF 
IF LI = 0 THEN 
COMPUTE ACCU = CR / CI 
END-IF 
DISPLAY ACCU 
STOP RUN. 

Variablen, strukturiert

Während der Implementierung von FizzBuzz haben wir lokale Variablen verwendet, ohne dabei auf die Datentypen weiter einzugehen. Sowohl Data Pictures als auch die dazugehörenden Value-Eigenschaften bieten Stellschrauben zur Anpassung des Programmverhaltens. OhmCalc bietet uns reichlich Möglichkeiten zum Experimentieren – betrachten Sie die Abbildungen 3 und 4, um zwei Seltsamkeiten am eigenen Leib zu erleben.

Abb. 3: COBOL scheint von Kommastellen keine Ahnung zu haben

Abb. 3: COBOL scheint von Kommastellen keine Ahnung zu haben

Abb. 4: Negative Zahlen sind nicht viel interessanter

Abb. 4: Negative Zahlen sind nicht viel interessanter

COBOLs Variablensystem unterscheidet sich gravierend von C, Java, JavaScript und Co. Dies ist in der Auslegung begründet: Die Sprache ist für die Bearbeitung von Lochkarten und ähnlichen zeichenorientierten Medien vorgesehen. Für Sie als Entwickler bedeutet dies, dass die Datentypen den auf der Lochkarte eingenommenen Platz beschreiben. Aus diesem Blickwinkel ist klar, warum COBOL-Strings immer eine fixe Länge haben: Nicht benutzte Zeichen bleiben auf der Lochkarte leer. Die Variablensektion von OhmCalc beheimatete folgende Variablenarten:

01 R PIC X(9).
01 CR PIC 9(9).
01 LR PIC 9(5).

PIC – die Mnemonik steht für Picture – beschreibt das Aussehen der Daten auf der Lochkarte durch eine Aneinanderreihung der in der Tabelle aufgelisteten Zeichen. Da 99999 oder XXXXXX unsauber aussehen, gibt es seit jeher die Möglichkeit zur Abkürzung durch Nutzung von Klammern.hanna_table_1
Mit diesem Wissen können wir uns an die „Reparatur“ des Rechenprogramms heranwagen. Dazu sind Änderungen an der Deklaration der numerischen Variablen notwendig (Listing 8).

01 CR PIC S9(6)V999.
01 CU PIC S9(6)V999.
01 CI PIC S9(6)V999.
01 LR PIC S9(6)V999.
01 LU PIC S9(6)V999.
01 LI PIC S9(6)V999.
01 ACCU PIC S9(6)V999.

Dank des S-Atttributs geht der Compiler fortan davon aus, dass die übergebenden Werte sowohl positiv als auch negativ ausfallen können. Das V gibt die Stelle des Kommas an: OhmCalc geht davon aus, dass die Zahlen aus maximal sechs Vorkomma- und drei Nachkommastellen bestehen.

Verschachtelte Programmierung

Selektionen und Iterationen lassen sich in COBOL fast beliebig verschachteln. Entwickler müssen dabei eine kleine Besonderheit beachten: Die als Terminator dienenden Punkte entwickeln in verschachteltem Code unerwünschtes Verhalten. Als erstes Beispiel dafür dient Listing 9, das – zumindest auf den ersten Blick – eine vernünftige und logische Ausgabe erzeugen sollte.

IDENTIFICATION DIVISION.
PROGRAM-ID. OHMCALC.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 VAL PIC 9(9) VALUE 22.

PROCEDURE DIVISION.
IF VAL

Wer das Programm kompiliert und ausführt, wird mit dem in Abbildung 5 gezeigten Resultat konfrontiert. Es ist offensichtlich, dass die Programmausführung nicht so erfolgt, wie man es auf den ersten Blick erwarten würde.

Abb. 5: Hier ist etwas faul ...

Abb. 5: Hier ist etwas faul …

Das seltsame Verhalten des Compilers liegt an einer Sondereigenschaft des Punkt-Operators. Er kündigt – wie in der Einleitung besprochen – das Ende eines Paragrafs bzw. Satzes an. Für unser Programm ist dies insofern kritisch, als offene Iterationen als Teil des Satzes gelten. Der Compiler fügt so viele END IF-Statements ein, wie zur „Komplettierung“ des Kommandos notwendig erscheinen. Compilerfehler erscheinen nur dann, wenn es – wie im hier verwendeten Beispiel – keinen Weg zur zwangsweisen Erzeugung von validem Code gibt.

Hierbei handelt es sich um einen klassischen Flüchtigkeitsfehler, der auch in kommerziellem Code immer wieder vorkommt. Es zahlt sich also stets aus, ein nicht plangemäß arbeitendes Programm auf überflüssige Punkte zu durchsuchen.

Bei der Erstellung von finanzmathematischen Applikationen erfreut COBOL seine Anwender mit einem höchst innovativen Feature. Selektionskriterien kommen häufig an mehreren Stellen von ein und demselben Programm vor. Listing 10 realisiert ein Programm, dass die „Preiswertheit“ von Silber anhand eines Vergleichs gegen einen Parameterbereich ermittelt.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 SILBERIN PIC X(9).
01 SILBERPREIS PIC 9(9) VALUE 0.
88 BILLIG VALUES ARE 0 THRU 50.

PROCEDURE DIVISION.
ACCEPT SILBERIN
MOVE SILBERIN TO SILBERPREIS
IF BILLIG THEN
DISPLAY 'Silber kaufen!'
ELSE
DISPLAY 'Hmm...'
END-IF

Die Besonderheit von cobolem.cbl liegt in der Verwendung eines benannten Kriteriums. Die in der Data Division mit der Leitzahl 88 anzulegende Deklaration bezieht sich immer auf die ihr vorangestellte Variable – im Fall unseres Beispiels wird verdrahtet. In der Selektion genügt daraufhin das einfache Absetzen einer Anfrage. Die Verwendung dieses Features ist unter anderem deshalb sinnvoll, weil sich das Verändern des Edelmetallpreises so an einer Stelle der Gesamtapplikation bewerkstelligen lässt.

COBOL kennt weitere Iterationsstrukturen, die die aus C und Co. bekannten Iterationen abdecken. In PERFORM UNTIL verbirgt sich eine kleine Falle für Quereinsteiger, die wir in Listing 11 kurz illustrieren.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 LAEUFER PIC 9(9) VALUE 0.

PROCEDURE DIVISION.
PERFORM WITH TEST AFTER UNTIL LAEUFER = 10
DISPLAY LAEUFER
ADD 1 TO LAEUFER
END-PERFORM

STOP RUN.

C und Co. führen eine Schleife so lange durch, wie die Bedingung wahr ist. In COBOL sieht die Lage insofern anders aus, als die Schleife nur beim False-Sein ausgeführt wird. Das als Default festgelegte WITH TEST BEFORE und sein Kollege WITH TEST AFTER erlauben die Auswahl zwischen Kopf- und Fußsteuerung der Iteration.

Beachten Sie, dass PERFORM nicht nur zur Realisierung von Iterationen dient. Ohne Bedingungen auftretende Varianten des Befehls dienen als Sprungorder in Unterprogramme – wir werden sie in einem folgenden Abschnitt genauer kennenlernen.

Stellen Sie Ihre Fragen zu diesen oder anderen Themen unseren entwickler.de-Lesern oder beantworten Sie Fragen der anderen Leser.

Array als Datenbank

Es gibt kaum einen Informatiker, der kein „Smart-Array“ in der Hinterhand hat. Die normalerweise als Datenstruktur für die Realisierung von Round Robin Buffers und ähnlichen Spielereien vorgesehenen Felder lassen sich mit etwas Glue-Code in hervorragende Minidatenbanken umwandeln.

Die am Anfang der Variablendeklaration stehenden Sequenzzahlen stellten für uns bisher ein nur wenig relevantes Ärgernis dar. Das ist insofern falsch, als sie die Realisierung von verschachtelten Variablen ermöglichen – als Beispiel dafür soll Listing 12 herhalten.

DATA DIVISION.

WORKING-STORAGE SECTION.

01 SILBERFELD.

    02 BARRENNAME PIC X(20).

    02 BARRENGEWICHT PIC 9(9) VALUE 0.

    02 BARRENMENGE PIC 9(9) VALUE 0.

COBOL zeigt sich bei der Interpretation der Zahlen insofern kooperativ, als die Sprache keine „Stride width“ vorschreibt. In der Literatur finden sich immer wieder Programmbeispiele, in denen die Verschiebung in Fünferschritten erfolgt. Da der Maximalwert XXX beträgt, sollten Sie eventuell auf Einserschritte setzen.

Der Zugriff auf die einzelnen Unterelemente der Struktur erfolgt nach dem in Listing 13 gezeigten Schema – sowohl OF als auch IN interagieren mit den enthaltenen Daten. DISPLAY wirft den Gesamtinhalt in die Konsole aus – es gibt Möglichkeiten zur Formatierung, auf die wir an dieser Stelle aber nicht weiter eingehen wollen.

PROCEDURE DIVISION.

MOVE 'PHILHARMONIKER' TO  BARRENNAME IN SILBERFELD

COMPUTE BARRENGEWICHT OF SILBERFELD = 23

DISPLAY SILBERFELD


STOP RUN.

Unser Edelmetallprogramm funktioniert so lange, wie es mit einer Edelmetallart auskommen muss. COBOL erlaubt die Erstellung von ein- und zweidimensionalen Arrays von Datenfeldern. Die neue Version des Silberfelds kann man Listing 14 entnehmen.

DATA DIVISION.

WORKING-STORAGE SECTION.

01 SILBERFELD.

    02 FELD OCCURS 10 TIMES.

    03 BARRENNAME PIC X(20).

    03 BARRENGEWICHT PIC 9(9).

    03 BARRENMENGE PIC 9(9).

OCCURS darf keinesfalls in Kombination mit einem Element der Ordnungszahl 01 aufscheinen, weshalb wir ein Ordinalelement einfügen. Der Zugriff auf die eigentlichen Inhalte erfolgt nun über den von anderen Sprachen bekannten Indexoperator:

PROCEDURE DIVISION.
MOVE 'PHILHARMONIKER' TO  BARRENNAME(1)
DISPLAY SILBERFELD
STOP RUN.

Da COBOL-Programme oft zur Verarbeitung ganzer Felder zum Einsatz kommen, gibt es mit Indizes ein Werkzeug zur sequenziellen Traversierung. Mit einem Index versehene Felder lassen sich sogar durchsuchen – ein Thema, dem wir uns an dieser Stelle aus Platzgründen nicht zuwenden können.

Hier muss Struktur rein

Unsere COBOL-Programme wurden bisher – im Großen und Ganzen – sequenziell abgearbeitet. Für kleinere Beispiele mag dies ausreichend sein, in komplexeren Systemen ist die Aufteilung in Unterprogramme wünschenswert. Als Erstes wollen wir das Anspringen einer Subroutine per PERFORM illustrieren. Es unterscheidet sich insofern von GOTO, als die „Rückkehr“ des Instruktions-Pointers hier vonseiten des Compilers sichergestellt wird (Listing 15).

PROCEDURE DIVISION.

DISPLAY 'Stufe A'

PERFORM SECTIONB

PERFORM SECTIONC

DISPLAY 'Stufe D'


STOP RUN.


SECTIONB.

DISPLAY 'Stufe  B'.

SECTIONC.

DISPLAY 'Stufe C'.

Da die meisten Implementierungen von COBOL keine „lokalen“ Variablen kennen, bieten Routinen nur eingeschränkten Spielraum zur Modularisierung. Als Alternative dazu bieten sich vollständige Unterprogramme an, die nach dem Schema in Listing 16 aufzubauen sind.

IDENTIFICATION DIVISION.

PROGRAM-ID. CALLEE.


DATA DIVISION.

LINKAGE SECTION.

   01 DATAIN PIC 9(4).


PROCEDURE DIVISION USING DATAIN.

DISPLAY DATAIN


EXIT PROGRAM.

Die LINKAGE SECTION beschreibt dabei die vom aufrufenden Programm anzuliefernden Werte, die im Rahmen des Aufrufs übertragen werden müssen. Die relevante Passage des Hosts finden Sie in Listing 17.

DATA DIVISION.

WORKING-STORAGE SECTION.

   01 DATAOUT PIC 9(4) VALUE 22.



PROCEDURE DIVISION.

CALL 'CALLEE' USING BY CONTENT DATAOUT.



STOP RUN.

Damit ist nur noch die Kompilation interessant, die durch Eingabe des folgenden Befehls bewerkstelligt wird:

tamhan@TAMHAN14:~/SUSCobol$ cobc -free -x -o runme host.cbl callee.cbl

Report, automatisiert

COBOL-Programme generieren Unmengen von als Reports bezeichneten Dokumenten. Wer einmal bei einer Ostmiliz gearbeitet hat, kennt die von Nadeldruckern auf Lochpapier ausgedruckten Aktenstapel mit Sicherheit. Das manuelle Erstellen eines Reports ist aufgrund der Positionierung ärgerlich Wer einmal von Hand ein Konsolenprogramm realisiert hat, kann über den Aufwand mit der Stringverarbeitung ein Lied singen.

Das CODASYL-Kommittee begegnete dieser Situation durch das Report-Writer-Modul. In Retrospektive muss es als Vorgänger der diversen Template-Engines gelten. Die dabei zum Einsatz kommende Vorgehensweise ist vergleichsweise einfach. Im ersten Schritt deklariert der Entwickler die Struktur des zu schreibenden Berichts. Im nächsten Akt wird dieser mit den im Programm befindlichen Daten „dotiert“, um zu guter Letzt in einen Drucker oder auf den Bildschirm zu wandern.

Da GnuCOBOL (vormals OpenCOBOL diesen Teil des Sprachstandards nicht unterstützt, besprechen wir die Funktion an dieser Stelle nicht weiter. Achten Sie darauf, dass jede Implementierung kleine Besonderheiten aufweist – beschaffen Sie im Zweifelsfall das Programmierhandbuch des zu verwendenden Systems.

JCL to go

GnuCOBOL unterscheidet sich insofern von klassischen COBOL-Interpretern, als es sich dem Entwickler gegenüber im Großen und Ganzen wie eine Abart von GCC verhält. Eine kompilierte COBOL-Anwendung lässt sich von der Kommandozeile aus aufrufen.

Im Mainframebereich kommt zur Ablaufsteuerung stattdessen die so genannte Job Control Language – kurz JCL – zum Einsatz. Da sie von GnuCOBOL nicht unterstützt wird, beschränken wir uns hier auf eine kurze Konzeptbeschreibung. Es handelt sich dabei um eine Sprache, die die im Rahmen eines Runs durchzuführenden Aufgaben formell beschreibt.

Mehr lernen

COBOL enthält eine Vielzahl von als Verben bezeichneten Kommandos. Die genaue Zahl unterscheidet sich je nach Dialekt und Implementierung. Aus der Logik folgt, dass dieser Artikel keine vollständige Beschreibung des Programmiersystems darstellt.

Neben dem auf tutorialspoint bereitgestellten Überblickstutorial haben diverse angelsächsische Universitäten ihre alten Kursmaterialien onlinegestellt. Sowohl die University of Limerick als auch The e-academy verdienen an dieser Stelle gesonderte Erwähnung. Die GnuCOBOL/OpenCOBOL-FAQ bietet eine Beschreibung aller im Compiler implementierten Funktionen und Intrinsics. Das Dokument ist auch deshalb lesenswert, weil es die Unterschiede zwischen GnuCOBOL und anderen Produkten beschreibt. Aus selbiger Quelle gibt es einen Programmer’s Guide, der den Compiler detailliert beschreibt. Da es zwischen den einzelnen COBOL-Implementierungen Unterschiede gibt, sollten Sie den Programmer’s Guide Ihres Wunschcompilers sorgfältig lesen.

Bücher stellen eine weitere Informationsquelle dar. Auf alibris.com finden sich Unmengen von alten Klassikern, die von Universitäten und öffentlichen Bibliotheken ausgelistet wurden. Wer nur ein oder zwei Bücher braucht, kann die Versandkosten von fünf bis zehnEuro pro Werk absorbieren. Bei größeren Bestellungen lohnt sich das Besuchen der Webseite der „Unterhändler“: Sie bieten in ihren eigenen Shops oft bessere Konditionen.

Fazit

COBOL unterscheidet sich von C und Co. schon aufgrund des Ansatzes. Die Entwickler versuchten, eine an normalen englischen Texten angelehnte Programmiersprache zu entwerfen. Wer sich an die zugegebenermaßen eigenwillige Syntax gewöhnt, kann mit der Sprache binnen vergleichsweise kurzer Zeit effektiv arbeiten.

Ob der unüblichen Herkunft – universitären Forschern war die Mitgliedschaft im CODASYL-Kommittee verwehrt – zeigt COBOL einige hoch interessante Mittel zur Produktivitätssteigerung auf, die heute in Vergessenheit geraten sind. Wer an einer eigenen Programmiersprache arbeitet, kann beim Urahn den einen oder anderen interessanten Shortcut abkupfern.

In der Praxis erweist sich der oft nur leidlich dokumentierte Legacy-Code als größtes Hindernis für angehende COBOL-Programmierer. Wer sich mit einem existierenden System befassen muss, sollte einige Zeit zur Einarbeitung einplanen. In der Anfangszeit der Programmierung sicherten Informatiker ihren Job gerne durch Erzeugung von für Dritte nur sehr schwer verständlichem Code.

Entwickler Magazin

Entwickler Magazin abonnierenDieser Artikel ist im Entwickler Magazin erschienen.

Natürlich können Sie das Entwickler Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Aufmacherbild: Computer mouse connected to vintage typewriter via Shutterstock / Urheberrecht: Amy Johansson

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -