Blue Theme Orange Theme Green Theme Red Theme
 
Home | Forums | ASP.NET 2.0 Tutorials | Web Services | How Do I...? | Class Browser | WPF Quick Starts | Advertise with Us
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
Nevron Chart
Search :       Advanced Search »
Home » COBOL .NET » Progressive Modernization Using Managed COBOL

Progressive Modernization Using Managed COBOL

An example of how Managed COBOL methods can be used to progressively add locally scoped storage to legacy COBOL code.

Page Views : 791
Downloads : 0
Rating :
 Rate it
Level : Beginner
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
 
Nevron Chart
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 


Context

Well Written Code Should Look Elegant. Here I am searching for an elegant way to ease legacy section/paragraph based COBOL into using Methods with all the associated benefits. 

When discussing COBOL what I hear over and over again as the number 1 disadvantage (from real COBOL programmers) compared to C,C# and Java etc. is the lack of local data. When writing a large COBOL program it becomes progressively more difficult to work out what is happening because all the parts of the program share the same working storage. It is possible to use local storage, but the natural unit of sub-division in a COBOL program is the paragraph or section (depending on house style). Writing a system with hundreds or even thousands of tiny, individual programs is poor style, and may well result in lacklustre performance. This means working storage becomes huge and complex and unwieldy.

Managed COBOL from Micro Focus has a complete solution to this issue. It supports classes, objects and methods in a very intuitive way.

But, what happens if we don't want to make the whole leap into OO programming at one go? What happens if you just want to move away from global storage and progressively modernize?

Whilst this is a huge and fascinating subject my aim here is just to take a first step and show some tricks and ideas. Maybe this can act to start of a bigger discussion or I might well come back to the subject in the future.

Taking advantage of Managed COBOL syntax can be done one tiny step at a time.

Methods offer loads of advantages over performed ranges or even calls. However, I don't want to have to rave about that for now. I just want to show the first step - moving from a pure procedural program to a mix of procedures and classes. To do that, let's take a example COBOL procedural program. I have written one which is deliberately now that nice. We can imagine that this program was written in a few minutes by someone and then has been extended a few times by someone else who did not really understand what it does.

We can get a pretty good idea of what the program and its history is about from the header comments:

      ********************************************
      * Yield table creator
      * ===================
      *
      * This program creates a yield table to show the
      * yield from our investment policy type Qr24.
      * It does this using the old computational system and
      * the new one as mantated by reg 123456 ordinace 988765.
      * Author: A.N. Other (Retired)
      *
      * Altered to produce several tables:
      * Author: A. Newbie
      ********************************************

Further, we can see that A. Newbie used 'perform through' style whilst A.N. Other  did not. This has lead to a mix of programming styles and the inevitable confusion. To make my example work as a story, we need to pretend this is a huge program which would take several days to unpick. But - we don't want to spend several days over this post, so the short example and a dose of imagination will have to do:

      ********************************************
      * Yield table creator
      * ===================
      * 
      * This program creates a yield table to show the 
      * yield from our investment policy type Qr24.
      * It does this using the old computational system and
      * the new one as mantated by reg 123456 ordinace 988765.
      * Author: A.N. Other Retired-Programmer
      *
      * Altered to produce several tables:
      * Author: A. Newbie
      ********************************************
      

       program-id. yield-table-creator.

       working-storage section.
       01 money-info.
         03 yield-old        pic 9(9)v99 comp.
         03 yield-new        pic 9(9)v99 comp.
         03 money            pic 9(9).99.

       01 calc-internals.
         03 n-current-balance pic 9(9)v9(7)  comp.
         03 n-interest-c      pic 9(9)v9(7)  comp.
         03 n-intermediate    pic 9(9)v9(7)  comp.
         03 o-current-balance pic 9(9)v9(5)  comp.
         03 o-interest-c      pic 9(9)v9(5)  comp.
         03 o-intermediate    pic 9(9)v9(5)  comp.
         03 calc-day          pic 9(9)       comp.
      
       01 yield-info.         
         03 start-balance     pic 9(9)v9(2)  comp.
         03 yield             pic 9(9)v9(2)  comp.
         03 interest          pic     v9(4)  comp.
         03 days              pic 9(9)       comp.
         03 years             pic 9(2)       comp.
         
       01 calc-info.
         03 start-at          pic 9(9)v9(2)  comp.
         03 end-at            pic 9(9)v9(2)  comp.
         03 step-by           pic 9(9)v9(2)  comp.
          
       procedure division.
       
           perform table-01 through table-04
           display "---== END RUN ==---"
           goback.
       
       table-01 section.
           move 0.0625 to interest
           move 9132   to days
           move 25     to years
           move 1      to start-at
           move 100    to end-at
           move 1      to step-by
           perform make-table
           .

       table-02 section.
           move 0.05   to interest
           move 9132   to days
           move 25     to years
           move 1      to start-at
           move 100    to end-at
           move 1      to step-by
           perform make-table
           .

       table-03 section.
           move 0.0625 to interest
           move 9132   to days
           move 25     to years
           move 100000 to start-at
           move 110000 to end-at
           move 100    to step-by
           perform make-table
           .

       table-04 section.
           move 0.05   to interest
           move 9132   to days
           move 25     to years
           move 100000 to start-at
           move 110000 to end-at
           move 100    to step-by
           perform make-table
           .
       
       make-table section.
           display "Conversion for:"
           multiply interest by 100 giving money
           display "Interest= " money "%"
           display "Days    = " days
           display "Years   = " years
           move start-at to money
           display "Start at= " money
           move end-at   to money
           display "End at  = " money
           move step-by  to money
           display "Step by = " money
           
           display "+--------------+--------------+--------------+--------------+"
           
           perform varying start-balance from start-at by step-by
                                until start-balance = end-at
              
               perform comp-yield-old
               move yield to yield-old
               
               perform comp-yield-new
               move yield to yield-new
               

               if yield-new not = yield-old 
                       move start-balance to money
                       display "| " money " | " with no advancing
                       move yield-old to money
                       display money " | " with no advancing
                       move yield-new to money 
                       display money " | " with no advancing
                       compute money = yield-old - yield-new
                       display money " |"
               end-if
                   
           end-perform
           
           display "+--------------+--------------+--------------+--------------+"
           display " "
           .
           
       comp-yield-new section.
           move    start-balance  to n-current-balance
           move    interest       to n-interest-c
           compute n-interest-c   rounded = (n-interest-c * years) / days
           compute n-intermediate rounded = n-interest-c
           move    n-intermediate to n-interest-c
           move    days to calc-day

           perform varying calc-day from 1 by 1 until calc-day greater days
               
               compute n-intermediate rounded
                       = n-current-balance + (n-current-balance * n-interest-c) 
               move    n-intermediate to n-current-balance
       
           end-perform
           move n-current-balance to yield
           .
           
       comp-yield-old section.
           move    start-balance  to o-current-balance
           move    interest       to o-interest-c
           compute o-interest-c   rounded = (o-interest-c * years) / days
           compute o-intermediate rounded = o-interest-c
           move    o-intermediate to o-interest-c
           move    days to calc-day

           perform varying calc-day from 1 by 1 until calc-day greater days
               
               compute o-intermediate rounded
                       = o-current-balance + (o-current-balance * o-interest-c) 
               move    o-intermediate to o-current-balance
       
           end-perform
           move o-current-balance to yield
           .

       end program yield-table-creator.

Which produces output like this:

Conversion for:
Interest= 000000006.25%
Days    = 000009132
Years   = 25
Start at= 000000001.00
End at  = 000000100.00
Step by = 000000001.00
+--------------+--------------+--------------+--------------+
| 000000001.00 | 000000004.72 | 000000004.77 | 000000000.05 |
| 000000002.00 | 000000009.44 | 000000009.54 | 000000000.10 |
| 000000003.00 | 000000014.16 | 000000014.31 | 000000000.15 |
| 000000004.00 | 000000018.88 | 000000019.08 | 000000000.20 |
| 000000005.00 | 000000023.61 | 000000023.85 | 000000000.24 |
| 000000006.00 | 000000028.33 | 000000028.62 | 000000000.29 |
| 000000007.00 | 000000033.05 | 000000033.39 | 000000000.34 |
| 000000008.00 | 000000037.77 | 000000038.16 | 000000000.39 |
| 000000009.00 | 000000042.50 | 000000042.93 | 000000000.43 |
| 000000010.00 | 000000047.22 | 000000047.70 | 000000000.48 |
| 000000011.00 | 000000051.94 | 000000052.47 | 000000000.53 |
| 000000012.00 | 000000056.66 | 000000057.24 | 000000000.58 |
| 000000013.00 | 000000061.39 | 000000062.01 | 000000000.62 |
| 000000014.00 | 000000066.11 | 000000066.78 | 000000000.67 |
| 000000015.00 | 000000070.83 | 000000071.55 | 000000000.72 |
| 000000016.00 | 000000075.55 | 000000076.32 | 000000000.77 |
| 000000017.00 | 000000080.27 | 000000081.09 | 000000000.82 |

Making Changes - Methods To The Rescue!

To continue our story, we are tasked with updating the new algorithm because we have found out that " reg 123456 ordinace 988765" requires that no interest in paid on every 7th day. Here is the solution:

       comp-yield-new section.
           move    start-balance  to n-current-balance
           move    interest       to n-interest-c
           compute n-interest-c   rounded = (n-interest-c * years) / days
           compute n-intermediate rounded = n-interest-c
           move    n-intermediate to n-interest-c
           move    days to calc-day
           move    1 to day-flagger

           perform varying calc-day from 1 by 1 until calc-day greater days
               if day-flagger = 7 
                   move 1 to day flagger
               else
                   compute n-intermediate rounded
                           = n-current-balance + (n-current-balance * n-interest-c) 
                   move    n-intermediate to n-current-balance
                   add 1 to day-flagger
               end-if
           end-perform
           move n-current-balance to yield
           .
I have added in 'day-flagger' to the algorithm. The snag is that I will now have to go and define it in working storage. In a real program - that working storage may well be defined in a copy book; do I add day-flagger to that copy book or mess up the format of this program by adding it to the code source file? This is only a simple example, in a massive program having to keep going back to working storage and adding stuff is a pain and increases the memory footprint of the program even when those added items are not being used.

The solution is to put in a bit of effort now for a lot benefit later. The solution is to move the guts comp-yield-new into a method and use 'invoke' to do my calculation:

       comp-yield-new section.
           invoke comp-class::comp-yield-new(yield-info)

Here is the code for the com-class and the comp-yield-new method in it.

       class-id comp-class public.
       
       method-id comp-yield-new public static.
       
       local-storage section.
       01 calc-internals.
         03 n-current-balance pic 9(9)v9(7)  comp.
         03 n-interest-c      pic 9(9)v9(7)  comp.
         03 n-intermediate    pic 9(9)v9(7)  comp.
         03 calc-day          pic 9(9)       comp.
         
       linkage section.
       01 yield-info.         
         03 start-balance     pic 9(9)v9(2)  comp.
         03 yield             pic 9(9)v9(2)  comp.
         03 interest          pic     v9(4)  comp.
         03 days              pic 9(9)       comp.
         03 years             pic 9(2)       comp.

       procedure division using yield-info.
           move    start-balance  to n-current-balance
           move    interest       to n-interest-c
           compute n-interest-c   rounded = (n-interest-c * years) / days
           compute n-intermediate rounded = n-interest-c
           move    n-intermediate to n-interest-c
           move    days to calc-day

           perform varying calc-day from 1 by 1 until calc-day greater days
               
               compute n-intermediate rounded
                       = n-current-balance + (n-current-balance * n-interest-c) 
               move    n-intermediate to n-current-balance
       
           end-perform
           move n-current-balance to yield
       end method.
       
       end class.

This is really just a cut a paste of the code from the perform, so I have had to put in a minimal amount of effort. I can put the 'yield-info' group in a copy file and that avoids me having to put any effort into the linkage section either! 
 
       linkage section.
           copy "yield-info.cpy"
 
To demonstrate the behaviour of the program is completely unchanged, here is a shot of the output: 


Both the comp-class and the comp-yield-new method are marked as public so that they can be accessed from anywhere. More sophisticated OO styles like protected and private members are not required at this early stage of modernization. Also of note is that the comp-yield-new method is marked static. This means it can be invoked in a similar way that COBOL entry points can be called. If it was not static, we would need to create an instance of comp-class and invoke the method on the instance. This is another more sophisticated OO style which we don't need to think about at this stage.

Now we get the pay off!

OK, we have gone to the (small amount of) effort to make our section (or paragraph) into a method. Now we must add in this 7 day rule. Wow - we don't need to mess with the working-storage of our main program, or even in the class; we can work with the local-storage in our method!

       method-id comp-yield-new public static.
       
       local-storage section.
       01 calc-internals.
         03 n-current-balance pic 9(9)v9(7)  comp.
         03 n-interest-c      pic 9(9)v9(7)  comp.
         03 n-intermediate    pic 9(9)v9(7)  comp.
         03 calc-day          pic 9(9)       comp.

       01 day-flagger         pic 9.
         
       linkage section.
           copy "yield-info.cpy"

       procedure division using yield-info.
           move    start-balance  to n-current-balance
           move    interest       to n-interest-c
           compute n-interest-c   rounded = (n-interest-c * years) / days
           compute n-intermediate rounded = n-interest-c
           move    n-intermediate to n-interest-c
           move    days to calc-day
           move    1 to day-flagger

           perform varying calc-day from 1 by 1 until calc-day greater days
               if day-flagger = 7 
                   move 1 to day flagger
               else
                   compute n-intermediate rounded
                           = n-current-balance + (n-current-balance * n-interest-c) 
                   move    n-intermediate to n-current-balance
                   add 1 to day-flagger
               end-if
           end-perform
           move n-current-balance to yield
       end method.

COBOL's biggest problem just went away!

I hope that I have shown how the transition from procedural COBOL to Managed OO COBOL can be really gentle, safe and easy.It also really important that modernization can make real differences straight away. 

Once the techniques for progressively modernizing procedural COBOL have been mastered, all that intellectual property locked away in COBOL programs can be re-used in new and exciting ways. Lots of little steps with lots of massive pay-offs.

For more on the issues discussed here please find the following resources:

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
alex turner
Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the top 5 tips for understanding .NET
Ricky Leeks presents the top 5 tips for understanding .NET Interoperability. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Nevron Chart
Become a Sponsor
 Comments
method vs nested program by Jeff On October 5, 2010

Thanks for the straight forward example of setting up a method in COBOL.  Can you also explain how this is different or preferable to placing the same code into a nested program.  It seems that would still support the concept of local variables without needing to learn "new" COBOL concepts such as methods.  Some explanation of examples of the advantages of methods over nested programs would be useful for me.

Reply | Email | Modify 
Nested Programs by alex On October 6, 2010
The biggest difference is that method allocate local storage on the stack and are fully recursive. However, in the static form they are represented here - they are a first step towards object structured coding.
Reply | Email | Modify 

 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.