• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Enumerated Data Types In RPG

    September 16, 2019 Ted Holt

    IT has changed a lot since I entered the field several decades ago, but some things have not changed. I would read in those early days that COBOL was dead, and I read the same thing now. Yet COBOL is 60 years old and still going strong. Back then I heard RPG criticized as “Real Poor Garbage”. These days I hear it scorned as “legacy”, which I assume is supposed to mean the same thing. Yet today’s RPG is better than any of its predecessors for business programming.

    RPG supposedly does not have the features of modern languages. Maybe not, but I have found that I can make RPG do what I need it to do anyway. One example is enumerated data types.

    An enumerated type is a data type with a restricted set of allowable values. They are wonderful because they preclude the option of assigning an invalid value to a variable. Currently hot languages like JavaScript, C# and Python support them, but they’re not new. I used enumerated types in Pascal in my university days. To learn more about enumerated types and see some examples, visit Wikipedia.

    RPG has no special syntax for enumerated types, but the existing syntax works quite well. Here’s how it’s done.

    Let’s say that we have a program that calls a subprocedure to process a batch of transactions of some sort. The subprocedure can operate in one of three modes:

    • It can validate the data, i.e. check the data for errors.
    • It can validate the data and post the data if it passes validation.
    • It can skip validation and post the data.

    Such a subprocedure would probably be part of a service program, but to simplify my example, I make it an internal subprocedure.

    The subprocedure returns a status code to report the result to the caller. Possible status codes are:

    • The subprocedure executed without error.
    • The subprocedure executed, but had to make some assumptions, and therefore generated one or more warning messages.
    • The subprocedure found an error condition.

    Here’s a copybook in which these data types are defined.

    **free
    dcl-s  Action_t       char(2)   template;
    dcl-c  Validate          'V ';
    dcl-c  Post              'P ';
    dcl-c  ValidateAndPost   'VP';
    
    dcl-s  RunStatus_t    packed(1) template;
    dcl-c  SuccessfulRun     0;
    dcl-c  RunWithWarning    1;
    dcl-c  RunFailed         2;
    

    I’ve defined two datatypes: Action_t and RunStatus_t. I like to end the datatype names with _t. Notice the TEMPLATE keyword on each declaration to prevent the compiler from allocating memory.

    For each datatype, I’ve defined a set of allowable values as constants. Since RPG is not case-sensitive, I prefer to make constants look like any other type of identifier.

    Any source member that includes this copybook can define variables and functions of these data types.

    Here’s an example caller:

    **free
    /include copybooks,DataTypes
    
    dcl-s  Stat          like(RunStatus_t);
    dcl-s  BatchNumber   packed(3);
    
    Stat = ProcessBatch (BatchNumber: ValidateAndPost);
    
    if Stat = RunFailed;
          // do something to handle the error
    endif;
    
    
    dcl-proc  ProcessBatch;
    
      dcl-pi  ProcessBatch      like(RunStatus_t);
         inBatch   packed(3)        const;
         inAction  like(Action_t)   const;
      end-pi;
    
      if (inAction = Validate
      or  inAction = ValidateAndPost);
         // calcs to validate the data
         if . . . some error condition . . .
            return RunFailed;
         endif;
      endif;
    
      if (inAction = Post
      or  inAction = ValidateAndPost);
         // calcs to post the data
         if . . . some error condition . . .
            return RunFailed;
         endif;
      endif;
    
      return SuccessfulRun;
    
    end-proc;
    

    Notice the variable, function, and function parameter that are defined with these data types.

    dcl-s  Stat          like(RunStatus_t);
    dcl-pi  ProcessBatch      like(RunStatus_t);
    inAction  like(Action_t)   const;
    

    The compiler would not prevent me from assigning literals or comparing to literals, but I never do. I always refer to the constants.

    return SuccessfulRun;
    if Stat = RunFailed;
    

    One last point I’d like to make is that I can truly use these template variables as if they were real data types, at least in most cases. For instance, I can use one of the constants in the INZ keyword.

    dcl-s Stat like(RunStatus_t) inz(RunFailed);
    

    This is not foolproof. The compiler won’t stop me from assigning an invalid value to a variable or assigning a literal for one type to a variable of another compatible type. Avoiding such errors is a matter of discipline, but it’s not an egregious task, and usually the errors stick out like a sore thumb. For example, this looks reasonable:

    Color = Blue;
    

    But this does not:

    Color = RunFailed;
    

    The newer languages certainly have their place, but that doesn’t mean that we should dump RPG overnight under the theory that anything new has to be better than anything old. RPG is an effective business programming language, and believe it or not, can do a lot that some critics say it can’t do.

    RELATED RESOURCE

    Wikipedia – Enumerated type

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, C, COBOL, FHG, Four Hundred Guru, IBM i, JavaScript, Python, RPG

    Sponsored by
    Raz-Lee Security

    With COVID-19 wreaking havoc, cybercriminals are taking advantage of the global impact that it has had on our families, our businesses and our societies. It is more important now than ever to ensure that IT systems are protected, so that when all of this is behind us, we can get back to business as usual as quickly as possible.

    iSecurity Anti-Ransomware protects organizations against ransomware attacks and other kinds of malware that may access and change business-critical data on your IBM i. It even protects against zero-day attacks. Anti-Viruses can only report on the damage an attack has caused, but not stop it.

    iSecurity Anti-Ransomware has been recently enhanced with a Self-Test feature that allows you to simulate a ransomware attack on your IBM i. The simulated attack is limited to the test folder and cannot harm any other folders or files. This new feature lets organizations see how they are protected against known or unknown ransomware.

    Key Features:

    • Real-time scanning for known and unknown ransomware threats.
    • Blocks and disconnects the intruder.
    • Instantaneously sends alerts to SIEM as well as the offending computer.
    • Self-Test for attack simulation
    • Classification of the attack based on log.
    • Automatic updates with the most current ransomware definitions.

    Contact us at https://www.razlee.com/anti-ransomware

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Unperspective: In Your Face New System z15 Mainframe Takes The Heat Off Power Systems

    2 thoughts on “Guru: Enumerated Data Types In RPG”

    • Jim Mitchell says:
      September 16, 2019 at 11:03 am

      Interesting article, Ted.

      It would not be difficult to check within the subprocedure to ensure the input variable contains one of those numerated values and return, say -1, if not. Thus strengthening the association of the enumerated list with the template variable.

      I’d love to see the Compiler offer a mechanism for enumerated values of a variable; or DB2 for that matter.

      IBM has ‘toyed’ with the idea from way back; as with the VALUES keyword in DDS.

      IBM has certainly brought RPG a long way to becoming truly competitive with other modern languages, that’s for sure! But there remains some challenges to be met.

      Thank you for your advocacy with thoughts such as this one.

      Reply
    • Jose Walker says:
      September 24, 2019 at 10:10 am

      Hello Ted.

      I use this DS:
      //
      D Task DS qualified
      D FillSFL 2s 0 inz(96)
      D Error 2s 0 inz(97)
      D BackPgm 2s 0 inz(98)
      D ExitPgm 2s 0 inz(99)
      D Init 2s 0 inz(0)
      D Continue 2s 0 inz(1)
      D Find 2s 0 inz(10)
      D GetData 2s 0 inz(20)
      D ShowSFL 2s 0 inz(30)
      D Print 2s 0 inz(40)
      D Selected 2s 0 inz(50)

      You can use RDI/WSDC autocomplete like: Task.Find

      Best Regards,
      Jose

      Reply

    Leave a Reply Cancel reply

TFH Volume: 29 Issue: 51

This Issue Sponsored By

  • Profound Logic Software
  • New Generation Software
  • ARCAD Software
  • Computer Keyes
  • WorksRight Software

Table of Contents

  • IBM Lab Services: Your IBM i All-Star Team
  • New System z15 Mainframe Takes The Heat Off Power Systems
  • Guru: Enumerated Data Types In RPG
  • Unperspective: In Your Face
  • Maxava Hits Multiple Targets With The Same HA Arrow

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Need An RPG Programmer? Nalashaa May Have You Covered
  • Every Day Has To Be Earth Day
  • Guru: Compare Pieces Of Source Members
  • As I See It: Ambivalence
  • IBM i PTF Guide, Volume 23, Number 16
  • Query Supervisor Gives Database Engineers New Power
  • IBM Unveils New and Improved IBM i Services
  • 3 Takeaways from the 2021 PowerTech Security Report
  • Four Hundred Monitor, April 14
  • IBM i PTF Guide, Volume 23, Number 15

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2021 IT Jungle

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.