RPG

145. RPG モジュラー・プログラミング

ILE 入門では、サービス・プログラム (*SRVPGM) の利用について解説したが
ILE-RPG でサブ・ルーチンではなく、プロシージャーを使うべきであるという重要な
ポイントについて、解説を加える。
RPG III に永年、携わってきた人から見れば、サブ・ルーチンで十分であるはずなのに
何故、わざわざプロシージャーとして定義する必要があるのかと思うかも知れない。
それにはいくつかの理由があるが、最大の理由は、オブジェクト指向、つまり
オブジェクト = プロシージャーの再利用にある。
ここではモジュラー・プログラミングと呼ばれるオブジェクト = プロシージャーの
再利用の方法について解説する。
わかりやすいようにステップ・バイ・ステップで説明を続けていくことにする。

1. SUB001 : 品種マスターの照会プログラム - サブルーチン版

最初に、SUB001:品種マスターの照会プログラム を紹介する。
これは品種マスター(HINSHU) の内容を照会するだけの、単純なプログラムであるが
品種名を検索するために、サブルーチン GET_HINSHU によって品種名を取得している例である。

----------------------------------------------------------------------------------------------
0001.00 H DFTNAME(SUB001) DATEDIT(*YMD/)                                        
0002.00 F**********  品種マスターの照会 - SUBR 版 ***************************** 
0003.00 FSUB001D   CF   E             WORKSTN                                   
0004.00 FHINSHU    IF   E           K DISK                                      
0005.00 F********************************************************************** 
0006.00 C*( 初期画面 )                                                          
0007.00 C*----------------------------------------------------+                 
0008.00 C     START         TAG                                                 
0009.00 C                   EXFMT     DSPHEAD                                   
0010.00 C*----------------------------------------------------+                 
0011.00 C*( CF03 )- 終了                                                        
0012.00 C     *IN03         IFEQ      *ON                                       
0013.00 C                   SETON                                        LR     
0014.00 C                   RETURN                                              
0015.00 C                   END                                                 
0016.00 C*( 実行キー )                                                          
0017.00 C                   EXSR      GET_HINSHU                                
0018.00 C*( 明細画面 )                                                          
0019.00 C*----------------------------------------------------+                 
0020.00 C                   EXFMT     DSPDTA01                                  
0021.00 C*----------------------------------------------------+             
0022.00 C                   GOTO      START                                 
0023.00 C******************************************************             
0024.00 C     GET_HINSHU    BEGSR                                           
0025.00 C******************************************************             
0026.00 C                   SETOFF                                       99 
0027.00 C     HNSCOD        CHAIN     HINSHU                             99 
0028.00 C                   ENDSR                                           
-----------------------------------------------------------------------------------------------
【 画面DSPFソース 】
-----------------------------------------------------------------------------------------------
0001.00      A*%%TS  SD  19940302  221529  QTR         REL-V2R2M0  5738-PW1     
0002.00      A*            11:59:33    QSECOFR     REL-R06M00  5714-UT1         
0003.00      A*%%EC                                                             
0004.00      A                                      DSPSIZ(24 80 *DS3)          
0005.00      A                                      MSGLOC(24)                  
0006.00      A                                      PRINT                       
0007.00      A          R DSPDTA01                                              
0008.00      A*%%TS  SD  19940302  221529  QTR         REL-V2R2M0  5738-PW1     
0009.00      A                                      TEXT(' 明細画面 01')        
0010.00      A                                      CF03(03 ' 終了 ')           
0011.00      A                                      CF12(12 ' 前画面 ')         
0012.00      A                                      SETOF(99)                   
0013.00      A                                      BLINK                       
0014.00      A                                  1 27' 品種マスターの照会 '      
0015.00      A                                      DSPATR(HI)                  
0016.00      A                                  3  2' 品種コード '              
0017.00      A            HNSCOD         4A  O  3 15                            
0018.00      A                                  4  2' 品種名 '                  
0019.00      A            HNSNAM        14O  O  4 15                            
0020.00      A                                 23  2'F3= 終了 '                 
0021.00      A                                 23 69'F12= 前画面 '        
0022.00      A          R DSPHEAD                                         
0023.00      A                                      TEXT(' 初期画面 ')    
0024.00      A*            11:59:33    QSECOFR     REL-R06M00  5714-UT1   
0025.00      A                                      CF03(03 ' 終了 ')     
0026.00      A                                      BLINK                 
0027.00      A                                  1 27' 品種マスターの照会 '
0028.00      A                                      DSPATR(HI)            
0029.00      A                                  3  2' 品種コード '        
0030.00      A            HNSCOD         4A  B  3 15                      
0031.00      A                                 23  2'F3= 終了 '           
-----------------------------------------------------------------------------------------------

2. MOD001 : 品種マスターの照会プログラム - プロシージャー版

次に、MOD001 : 品種マスターの照会プログラムは SUB001 のサブルーチン : GET_HINHU
プロシージャー : GET_HINSHU に置き換えたものである。
プロシージャー : GET_HINSHU は、将来の再利用に備えて EXPORT として公開を宣言している。

-----------------------------------------------------------------------------------------------
0001.00 H DFTNAME(MOD001) DATEDIT(*YMD/)                                       
0002.00 F**********  品種マスターの照会 - MODULE 版 ***************************
0003.00 FMOD001D   CF   E             WORKSTN                                  
0004.00 FHINSHU    IF   E           K DISK                                     
0005.00 F**********************************************************************
0006.00 D GET_HINSHU      PR            14                                     
0007.00 D  HNSCOD                        4A   VALUE                            
0008.00 C*( 初期画面 )                                                         
0009.00 C*----------------------------------------------------+                
0010.00 C     START         TAG                                                
0011.00 C                   EXFMT     DSPHEAD                                  
0012.00 C*----------------------------------------------------+                
0013.00 C*( CF03 )- 終了                                                       
0014.00 C     *IN03         IFEQ      *ON                                      
0015.00 C                   SETON                                        LR    
0016.00 C                   RETURN                                             
0017.00 C                   END                                                
0018.00 C*( 実行キー )                                                         
0019.00 C                   EVAL      HNSNAM = GET_HINSHU(HNSCOD)              
0021.00 C*----------------------------------------------------+               
0022.00 C                   EXFMT     DSPDTA01                                
0023.00 C*----------------------------------------------------+               
0024.00 C                   GOTO      START                                   
0025.00 C******************************************************               
0026.00  *   GET_HINSHU :   品種名の取得                                      
0027.00 C******************************************************               
0028.00 P GET_HINSHU      B                   EXPORT                          
0029.00 D GET_HINSHU      PI            14                                    
0030.00 D  HNSCOD                        4A   VALUE                           
0031.00 C                   SETOFF                                       99   
0032.00 C     HNSCOD        CHAIN     HINSHU                             99   
0033.00 C                   RETURN    HNSNAM                                  
0034.00 P GET_HINSHU      E                                                   
-----------------------------------------------------------------------------------------------
【 解説 】
0006.00 D GET_HINSHU      PR            14           
0007.00 D  HNSCOD                        4A   VALUE  

によって、これから使用するプロシージャーのプロトタイプを予め宣言している。
プロシージャーは C/400 や Java と同じように使用する前に型を宣言しておく必要がある。
型さえプロトタイプで宣言しておけば、CRTRPGMOD の時点では、プロシージャーの実体は、
このソースに含まれていなくてもよい。
後で CRTPGM によってプログラムを作成するときに名前解決できればよいのである。
さて、GET_HINSHU というプロシージャーは


0025.00 C******************************************************               
0026.00  *   GET_HINSHU :   品種名の取得                                      
0027.00 C******************************************************               
0028.00 P GET_HINSHU      B                   EXPORT                          
0029.00 D GET_HINSHU      PI            14                                    
0030.00 D  HNSCOD                        4A   VALUE                           
0031.00 C                   SETOFF                                       99   
0032.00 C     HNSCOD        CHAIN     HINSHU                             99   
0033.00 C                   RETURN    HNSNAM                                  
0034.00 P GET_HINSHU      E 

で定義されている。
サブルーチンと、異なるのは、このプロシージャーはHNSCOD という 4A の文字列を
パラメータとして受け取って 14 桁の品種名を結果として戻すという関数であることである。
プロシージャーの演算は、それ自体で完結しており、必要であれば
プロシージャー内の D-仕様書でローカル変数を宣言することができる。
プロシージャー内で定義されるローカル変数は、他の演算からは保護されていて
プロシージャー外の演算からはアクセスすることができない。
これに対してサブルーチンの場合はグローバル変数としてサブルーチン内で使用する変数は
すべて,そのプログラム全体に共通して使用可能なものであることは、既に読者は
よくご存知のことであると思う。
これに対してプロシージャーは、それ自体がカプセル化した独立した演算となっている。

3.プロシージャー版 MOD001 のコンパイル

それでは、いつものように MOD001 を次のような手順でコンパイルしてみよう。

CRTRPGMOD QTEMP/MOD001 SRCFILE(MYSRCLIB/QRPGLESRC) AUT(*ALL)
CRTPGM MYLIB/MOD001 MODULE(QTEMP/MOD001) ACTGRP(*NEW) AUT(*ALL)

CALL MYLIB/MOD001 + [実行] してみるとサブルーチンで記述した SUB001 と同じ結果と
なるはずである。

4. モジュールを調べてみる。

ところで上記でCRTRPGMOD によって作成された QTEMP 上のモジュール : MOD001 を、
もう少し調べてみよう。

DSPMOD QTEMP/MOD001 + [実行] で見てみると、

次のようにプロシージャーがエススポート(公開)されていることがわかる。

つまり、

メイン・ルーチン           : MOD001
品種名の検索プロシージャー : GET_HINSHU

の2つが公開されていることがわかる。
このことによって他のプログラムでも、これらを CRTPGM のときにバインドして再利用することが
できることが、おわかりであろう。

5. モジュールを再利用する。

上記で作成されたプロシージャー GET_HINSHU を再利用するプログラム : MOD002 を作ってみよう。

-----------------------------------------------------------------------------------------------
0001.00 H DFTNAME(MOD002) DATEDIT(*YMD/)                                       
0002.00 F**********  品種マスターの照会 - *MODULE の再利用 ********************
0003.00 FMOD002D   CF   E             WORKSTN                                  
0004.00 F**********************************************************************
0005.00 D GET_HINSHU      PR            14                                     
0006.00 D  HNSCOD                        4A   VALUE                            
0007.00 C*( 初期画面 )                                                         
0008.00 C*----------------------------------------------------+                
0009.00 C     START         TAG                                                
0010.00 C                   EXFMT     DSPHEAD                                  
0011.00 C*----------------------------------------------------+                
0012.00 C*( CF03 )- 終了                                                       
0013.00 C     *IN03         IFEQ      *ON                                      
0014.00 C                   SETON                                        LR    
0015.00 C                   RETURN                                             
0016.00 C                   END                                                
0017.00 C*( 実行キー )                                                         
0018.00 C                   EVAL      HNSNAM = GET_HINSHU(HNSCOD)              
0019.00 C*( 明細画面 )                                                         
0020.00 C*----------------------------------------------------+                
0021.00 C                   EXFMT     DSPDTA01                 
0022.00 C*----------------------------------------------------+
0023.00 C                   GOTO      START                    
-----------------------------------------------------------------------------------------------
【 解説 】

再利用となると記述は極めてシンプルで簡単なものになる。
ここでは品種マスターそのものも定義されていない。
プロシージャー : GET_HINSHU は、このプログラムには実体はないが、プロトタイプが
宣言されているので CRTRPGMOD のコンパイル・エラーとはならない。

CRTRPGMOD MODULE(QTEMP/MOD002) SRCFILE(PGMRLIB/QRPGLESRC) AUT(*ALL)

でモジュールを QTEMP に作成してから、

CRTPGM PGM(MYLIB/MOD002) MODULE(QTEMP/MOD002 QTEMP/MOD001) ACTGRP(*NEW) AUT(*ALL)

で、再利用する QTEMP/MOD001 もあわせてバインドすればよい。

6.モジュラー・プログラミングのまとめ

上記では *MODULEQTEMP に作成したが、どこかの明示的なライブラリーに作成しておいて
そのライブラリーをバインド・ディレクトリーに登録しておけば、
バイント・ディレクトリーを RPG ソースの H-仕様書に登録するか、または CRTPGM のときに
指定すれば、かつてに作成したモジュールを、いくらでも再利用することができる。
現在、米国では 「RPG の近代化」(RPG Modernization) が話題の中心となっていて
RPG の再エンジニアリングが最も注目されている。
こういった中でサブ・ルーチンではなく、プロシージャーを使うように変更すればカプセル化されて
保守性も高まり、他人が見やすいプログラムとなる。
また、ここで紹介したモジュラー・プログラミングにすればモジュールを再利用することができる。

ただし、*SRVPGM に比べて *MODULE の再利用は *MODULE が変更されたときは、
その *MODULE をバインドしている *PGM も再コンパイルの必要があることを注意していて欲しい。
*SRVPGM にすべきか、どうか判断ができない場合でも *MODULE を残しておけば再利用率は
高まるのである。
Java が最初に注目されたのは、Java として作成されたオブジェクトは、すべて class という
同じオブジェクトであり、上位のJava から必ず利用することができるという
「オブジェクト指向」であった。
VC++ も、また世界中に広がっている数千万 ... の VC++ のオブジェクトは、すべてたったひとつの
クラスから派生して生成されていると言われている。
これまで RPG が、あまりにも生産性が良く、カンタンに開発することができてしまうので
オブジェクトの再利用の必要性が問われなかったに過ぎない。
しかし企業法人の保有するソフトウェア資産は、いまや莫大な数に登っている。
10 年以上、同じプログラムを動作させているとしたら、安全も大事ではあるが
ソフトウェアの近代化、つまりリエンジアリングが必要な時期にさしかかっていると考えてよいだろう。