While reading a article on-line about using “NACA transcoder” to translate COBOL into Java
it got me thinking about modernizing COBOL.
While I agree 100% about the actual code generated by the NACA transcoder is not
maintainable, I disagree that converting it to C# helps you modernize the code is
the only solution.
Using Visual COBOL the same code can be cut-pasted into a Class that exposes itself
in the same way as the C# he produces. Moving a legacy COBOL program into a Class
is just one way of reusing COBOL but in order to compare like with like, below is
the actual COBOL Class. This COBOL class can be compiled using Visual COBOL to
a .Net assembly or Java bytecode.
class-id Example public. working-storage section. 01 COMPANY. 05 COMPANY-NAME PIC X(60) VALUE "Semantic Designs". 05 COMPANY-ADDRESS. 10 STREET PIC X(80) VALUE "13171 Pond Springs Rd.". 10 CITY. 15 CITY-NAME PIC X(40) VALUE "Austin". 15 FILLER PIC XX VALUE ", ". 15 CITY-STATE PIC XX VALUE "TX". 15 ZIP. 20 ZIP-5 PIC 9(5) VALUE 78729. 20 FILLER PIC X VALUE "-". 20 ZIP-E4 PIC 9(4) VALUE 7102. 01 LINE-ITEM. 05 ITEM PIC X(20) VALUE "Item Description". 05 AMOUNT PIC 999 VALUE 217. 05 PRICE PIC 9999V99 VALUE 24.95. 77 TOTAL-AMOUNT PIC 999999V99. 77 DISCOUNT-THRESHOLD PIC 999999V99 VALUE 1111.11. 77 DISCOUNT-PERCENT PIC 99 VALUE 20. 77 DISCOUNT-AMOUNT PIC 99999999V99. 01 TOTAL-AMOUNT-FORMAT PIC 999999.99. 01 TotalAmount string public. method-id ComputeTotal. procedure division. MULTIPLY AMOUNT BY PRICE GIVING TOTAL-AMOUNT. IF TOTAL-AMOUNT > DISCOUNT-THRESHOLD MULTIPLY TOTAL-AMOUNT BY DISCOUNT-PERCENT GIVING DISCOUNT-AMOUNT DIVIDE 100 INTO DISCOUNT-AMOUNT SUBTRACT DISCOUNT-AMOUNT FROM TOTAL-AMOUNT. move TOTAL-AMOUNT to TOTAL-AMOUNT-FORMAT set TotalAmount to TOTAL-AMOUNT-FORMAT goback. end method. method-id. DisplayTotal. procedure division. DISPLAY COMPANY-NAME. DISPLAY "Total: ", TOTAL-AMOUNT-FORMAT end method. method-id. PerformTask. procedure division. invoke self::ComputeTotal() invoke self::DisplayTotal() end method. end class.
A C# program that uses the class above…. the same can also be done with Java…
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace UseExample { class Program { static void Main(string[] args) { new Example().PerformTask(); } } }
Another approach would be keep the legacy COBOL and create a wrapper class
that just uses the legacy COBOL.
class-id Example2. working-storage section. method-id ComputeTotal. procedure division. call "COMPUTE-TOTAL". goback. end method. method-id. DisplayTotal. procedure division. call "DISPLAY-TOTAL". end method. method-id. PerformTask. procedure division. invoke self::ComputeTotal() invoke self::DisplayTotal() end method. end class.
Then to make the DISPLAY-TOTAL, COMPUTE-TOTAL accessible to the class add two entry-points so
they can be used with the CALL verb eg:
EXTERNAL-EPS. ENTRY "DISPLAY-TOTAL". PERFORM DISPLAY-TOTAL. GOBACK. ENTRY "COMPUTE-TOTAL". PERFORM COMPUTE-TOTAL. GOBACK.
I personally think this it is quite a reasonable way to reuse COBOL…. plus the same code works under CLR
and JVM…. bonus….