RPG

201. RPGソース の近代化 (1)

RPG III から ILE-RPG に進化してから15年以上は経過しているので今だに
RPG III を書いている開発者は、さすがに少なくなってきている。
しかし、ここに来て RPG は、これからも残るのだろうか ? という不安とともに
確かに RPG の開発人口は少なくなってきている事実は否めない。
そこで新規に RPGソースを記述するにしても、オープン系の開発言語に
近い書き方をすれば、スタイリッシュで見やすくわかりやすいソースになるはずである。
米国雑誌などでは RPG は /FREE 〜 /END-FREE によるフリー・フォーマットが全盛であり、
固定フォーマットによるソース・サンプルはまず見られない。
残念ながらわが国ではフリー・フォーマットの RPG ソースは、まだまだ普及や浸透は
していないが、それでもホンの少しの工夫によってRPG ソースは見やすくわかりやすくなる余地は
まだまだ残されている。
レガシーな方法でも動作するからいい、と言っていたのでは貴方のソースは次の世代の人にとって
見難いソースだと思われてしまうだろう。
このシリーズでは、少しの工夫によって RPG ソースを近代化させるテクニックを順を追って紹介していこう。

第一回は、「標識を無くしてスッキリ・ソースに !!」 である。

■ 標識を無くしてスッキリ・ソースに !!

初めて RPG を学習する人にとって RPG の標識という概念が理解しずらいようである。
標識とはある事象がオン(ON)であるかオフ(OFF)であるかを示すためのフラグであり
オープン系でもブール変数(Boolean) として利用されている。
オープン系ではブール変数は名前で BOOL m_bSIGN のように示されるがRPG の標識は
01, 02, ... L1, L2, LR のように数字または記号であるので直ちに意味を読み取りにくい。
一時的な標識は xx で、NOT CHAIN の標識は xx, エラーの場合は xx のようにある程度、
開発グループでは取り決めしているようであるがこれも他社へ行くと統一性は崩れてしまう。
また結果の標識の位置も 54桁目( > )、56桁目( < ),58桁目( = ) とあるがこの位置を
SEU でひと目で読み取ることは困難である。
このように標識の利用は他人が見ると読みにくいソースになるケースが多いものである。
そこで標識による制御をなくしてしまえば、プログラマーによる個性を少なくして理解しやすい
ソースにすることができる。
RPG は OS V5R1M0 で大幅に機能強化が行われており組込み関数が充実してきている。

ブール変数

論理の真(TRUE) または偽(FALSE) を示す論理値を入れるための変数のことであり、
論理和(OR) や論理積(AND) を組み合わせた数式を扱う数学のことをブール代数と呼ぶ。

● CHAIN 命令の近代化

伝統的な CHAIN 命令による演算の例を示す。

[ 旧記述によるCHAIN命令の RPG ソース例 ]

0001.00 C******************************************************
0002.00 C     CHECK         BEGSR
0003.00 C******************************************************
0004.00 C                   SETOFF                                       99
0005.00 C     SHOKEY        CHAIN     SHOHIN                             99
0006.00 C   99              MOVEL     CODERR        ERRMSG
0007.00 C   99              GOTO      CHKEND
0008.00 C                   MOVEL     SHNAME        NMR(1)
0009.00 C                   Z-ADD     SHTANK        TKR(1)
0010.00 C     CHKEND        ENDSR

CHAIN が失敗しときの標識として 99 がオンになるように記述しているが
99 が記述されている位置が RPG にまだ不慣れな人には読み取りにくい。

[ %FOUND を使った新しい記述 ]

0001.00 C******************************************************
0002.00 C     CHECK         BEGSR
0003.00 C******************************************************
0004.00 C     SHOKEY        CHAIN     SHOHIN
0005.00 C                   IF        NOT %FOUND
0006.00 C                   EVAL      ERRMSG = CODEERR
0007.00 C                   LEAVESR
0008.00 C                   ELSE
0009.00 C                   EVAL      NMR(1) = SHNAME
0010.00 C                   EVAL      TKR(1) = SHTANK
0011.00 C                   ENDIF
0012.00 C                   ENDSR

CHAIN が成功すれば %FOUND が真になるので、失敗したときは NOT %FOUND である。
%FOUND%FOUND(SHOHIN) のようにして、ファイル名を指定して使用することもできる。
また MOVEMOVEL の代わりに EVAL を使って記述し、サブルーチンの終了にも
LEAVESR が抜けるようになっている。

● READ 命令の近代化

伝統的な READ 命令による演算の例を示す。

[ 旧記述によるREAD 命令の RPG ソース例 ]

0001.00 C                   DO        *HIVAL
0002.00 C                   SETOFF                                       50
0003.00 C                   READ      SHOHIN                                 50
0004.00 C   50              LEAVE
0005.00 C                   END

READ 命令によってファイルの読み取り終了(EOF = END OF FILE) になったら
58 桁目に記述してある標識 50 がオン(ON)となり、標識 50 がオンであれば
DO-LOOP を終了するという読み取りのLOOP文である。

[ %EOF を使った新しい記述 ]

0001.00 C                   DO        *HIVAL
0002.00 C                   READ      SHOHIN
0003.00 C                   IF        %EOF
0004.00 C                   LEAVE
0005.00 C                   ENDIF
0006.00 C                   END

EOF になると組込み関数 %EOF が真となることを判断して LOOP を抜けるように
変更されている。

● LOOKUP の近代化

[ 旧記述によるLOOKUP 命令の RPG ソース例 ]

0001.00 C                   Z-ADD     1             N                 4 0
0002.00 C     SHCODE        LOOKUP    CDR(N)                                 50
0003.00 C   50              MOVEL     NMR(N)        SHNAME

[ %FOUND を使った新しい記述 ]

0001.00 C                   Z-ADD     1             N                 4 0
0002.00 C     SHCODE        LOOKUP    CDR(N)                                 50
0003.00 C                   IF        %FOUND
0004.00 C                   MOVEL     NMR(N)        SHNAME
0005.00 C                   ENDIF

LOOKUP の場合、結果の位置への標識の指定は必ず必要とはなるが
%FOUND を使って記述することができる。
%FOUND を使えば RPG ソースの読み手に、明確にわかりやすく意図を伝えることが
できるようになる。この場合は %FOUND の代わりに %EQUAL でもよい。

● OPEN の近代化

[ 旧記述によるLOOKUP 命令の RPG ソース例 ]

0001.00 FSHOHIN    IF   E           K DISK    USROPN
0002.00
0003.00 C     *IN80         IFEQ      *OFF
0004.00 C                   OPEN      SHOHIN                               99
0005.00 C  N99              SETON                                        80
0006.00 C                   ENDIF

標識 80 がオンの場合は商品マスター(SHOHIN) がオープン済みであることを
表している。最初は N80 であるので、そのときだけ SHOHIN をオープンして
オープンが成功すれば、標識 80 をオンにしている。
%OPEN を使えば、指定したファイルがオープンされているのかどうかを
検査することができる。

[ %FOUND を使った新しい記述 ]

0001.00 FSHOHIN    IF   E           K DISK    EXTFILE(SHOHIN_LIB)
0002.00 F                                     USROPN
0003.00
0004.00 D SHOHIN_LIB      S             21    INZ('QTRFIL/SHOHIN')
0005.00
0006.00 C                   IF        NOT %OPEN(SHOHIN)
0007.00 C                   OPEN      SHOHIN
0008.00 C                   ENDIF
● SCAN の近代化

%FUOND を使えば SCAN 命令も標識を定義する必要がない。
次の例では STRING 中に NAME が見つかれば %FOUND が真になる。

0001.00 C     NAME          SCAN      STRING
0002.00 C                   IF        %FOUND
0003.00 C                   EXSR      CHECK
0004.00 C                   ENDIF
● CHECK や CHECKR の近代化

次の例では文字フィールド SHANAME の中に実際に収められている文字数を検出している。

0001.00 C     ' '           CHECKR    SHNAME        LEN               4 0
0002.00 C                   IF        %FOUND
0003.00 C                   EXSR      LENCHK
0004.00 C                   ENDIF