Robust RPG Programming with Assertions Ted Holt Senior
Robust RPG Programming with Assertions Ted Holt Senior Software Developer Profound Logic Software Senior Technical Editor Four Hundred Guru www. itjungle. com
Fill in the blank: Never ________!
Never assume!
Common assumptions ● ● ● A certain file will always exist. A field or variable will be large enough. A chain (random read) will always succeed.
The Problem of Assumptions ● ● ● May allow a program to use bad data May allow the database to be corrupted May mislead a decision-maker
When you assume, you make an ass of u and me! - Felix Unger
An assertion. . . verifies that a condition is true. . stops execution if it isn't.
An assertion. . . gives confidence that a program is working correctly. . is like insurance. You hope you never need it.
An assertion. . . is probably most valuable during development, testing, and debugging, but may also be used in production.
An assertion. . . codifies and enforces documentation. . can validate some things that the compiler can't.
Useless comment C* Callers must pass exactly 3 C* parameters. No more and no C* less!!!!!!!!!!!! C *ENTRY PLIST C PARM SITE C PARM ITEM C PARM REVISION
Valuable assertion /free assert (%parms = 3);
Common uses ● Verify number of parameters. ● Verify data values. ● ● Verify that a required I/O operation succeeded. Verify that a file opened.
Implementation in RPG ● ● ● Implemented as a subprocedure in an ILE module. Module may be listed in a binding directory. Binding directory is listed in the BNDDIR parameter of the H spec.
Implementation in RPG (Basic idea) CRTRPGMOD MODULE(somelib/ASSERT) SRCFILE(QRPGLESRC) SRCMBR(ASSERT) CRTRPGMOD MODULE(somelib/somepgm) SRCFILE(QRPGLESRC) SRCMBR(somepgm) CRTPGM PGM(somelib/somepgm) MODULE(somepgm ASSERT) ACTGRP(*CALLER)
Implementation in RPG (My preference) CRTRPGMOD MODULE(somelib/ASSERT) SRCFILE(QRPGLESRC) SRCMBR(ASSERT) ADDBNDDIRE BNDDIR(somelib/MYBNDDIR) OBJ((ASSERT *MODULE *IMMED)) In my RPG programs: H dftactgrp(*no) actgrp(whatever) H bnddir('MYBNDDIR')
Source Code ● Latest version: The RUN Utility: Call a Program with Correctly Formatted Parameters http: //www. itjungle. com/fhg 11 0106 -story 02. html
Source Code ● Also see this article: Programming with Assertions http: //www. itjungle. com/fhg 04 2104 -story 02. html
Subprocedure parameters (1)A condition that must be true, or else. (2) (optional) Text for escape message CPF 9898, which is sent to the caller if the first parameter proves to be false.
Subprocedure parameters /free assert (Bal. Due >= *zero: 'Negative balance found'); or assert (Bal. Due >= *zero);
An effective message should include: ● ● Program/procedure name A way to indicate which assertion failed ● Error description ● Identifying data
An effective message assert (Bal. Due >= *zero: %trim(psds. Proc. Name) + ' 40: Customer ' + %char(Cus. Num) + ' has a balance of ' + %editc(Bal. Due: 'J'));
Calling procedures must. . . ● ● ● . . . be compiled as if they will not run in the default activation group. . include a prototype to the assert subprocedure in order to invoked assert with callp. . use callp to invoke the assert subprocedure.
Calling procedures may. . . ● ● . . . need a copybook for the PSDS. . need compiler directives to condition assertions (e. g. to run only during development, testing and debugging).
An effective message AR 538 40: Customer 77 has a balance of 72. 18 -.
To get a dump Subordinate assert to the condition. ● Code *OFF in the first parameter. ● Dump before asserting. ●
To get a dump If (Bal. Due < *zero); dump(a); assert (*off: %trim(psds. Proc. Name) + ' 40: Customer ' + %char(Cus. Num) + ' has a balance of ' + %editc(Bal. Due: 'J')); endif;
Example 1 /FREE open Site; read Siter; assert (not %eof(): 'No default site. '); close Site; g. Site = Site. Id;
Example 2 dcl-s All. Files. Are. Open ind inz(*on); monitor; open BILLING; open SHIPPING; on-error; All. Files. Are. Open = false; endmon; Assert (All. Files. Are. Open: 'One or more files did not open; + program ' + %trimr(psds. Proc. Name) + ' canceled');
Example 3 Cust. Ndx = <some calculation>; assert (Cust. Ndx > *zero and Cust. Ndx <= %elem(Cust. Total): 'Cust. Ndx ' + %char(Cust. Ndx) + ' should be between 1 and ' + %char(%elem(Cust. Total))); . . . many lines of code omitted. . . Cust. Total (Cust. Ndx) += Cust. Amount;
Remember! ● ● Assertions are only for fatal errors. Calling assert cancels the program.
For more information https: //en. wikipedia. org/wiki/Assertion_%28 software_development%29 Philip J. Guo, University of Rochester The benefits of programming with assertions (a. k. a. assert statements) http: //www. pgbovine. net/programming-with-asserts. htm Code Carabiners http: //www. pgbovine. net/code-carabiners. htm How to use assertions to make your code more reliable http: //www. pgbovine. net/assertions-debugging-testing-lecture. htm
Contact info Ted Holt fourhundredguru@gmail. com
- Slides: 33