ILE 入門では、サービス・プログラム (*SRVPGM
) の利用について解説したが
ILE-RPG でサブ・ルーチンではなく、プロシージャーを使うべきであるという重要な
ポイントについて、解説を加える。
RPG III に永年、携わってきた人から見れば、サブ・ルーチンで十分であるはずなのに
何故、わざわざプロシージャーとして定義する必要があるのかと思うかも知れない。
それにはいくつかの理由があるが、最大の理由は、オブジェクト指向、つまり
オブジェクト = プロシージャーの再利用にある。
ここではモジュラー・プログラミングと呼ばれるオブジェクト = プロシージャーの
再利用の方法について解説する。
わかりやすいようにステップ・バイ・ステップで説明を続けていくことにする。
最初に、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 -----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------- 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= 終了 ' -----------------------------------------------------------------------------------------------
次に、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-仕様書でローカル変数を宣言することができる。
プロシージャー内で定義されるローカル変数は、他の演算からは保護されていて
プロシージャー外の演算からはアクセスすることができない。
これに対してサブルーチンの場合はグローバル変数としてサブルーチン内で使用する変数は
すべて,そのプログラム全体に共通して使用可能なものであることは、既に読者は
よくご存知のことであると思う。
これに対してプロシージャーは、それ自体がカプセル化した独立した演算となっている。
それでは、いつものように MOD001
を次のような手順でコンパイルしてみよう。
CRTRPGMOD QTEMP/MOD001 SRCFILE(MYSRCLIB/QRPGLESRC) AUT(*ALL) CRTPGM MYLIB/MOD001 MODULE(QTEMP/MOD001) ACTGRP(*NEW) AUT(*ALL)
CALL MYLIB/MOD001
+ [実行] してみるとサブルーチンで記述した SUB001
と同じ結果と
なるはずである。
ところで上記でCRTRPGMOD
によって作成された QTEMP
上のモジュール : MOD001
を、
もう少し調べてみよう。
DSPMOD QTEMP/MOD001
+ [実行] で見てみると、
次のようにプロシージャーがエススポート(公開)されていることがわかる。
つまり、
メイン・ルーチン : MOD001 品種名の検索プロシージャー : GET_HINSHU
の2つが公開されていることがわかる。
このことによって他のプログラムでも、これらを CRTPGM
のときにバインドして再利用することが
できることが、おわかりであろう。
上記で作成されたプロシージャー 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
もあわせてバインドすればよい。
上記では *MODULE
を QTEMP
に作成したが、どこかの明示的なライブラリーに作成しておいて
そのライブラリーをバインド・ディレクトリーに登録しておけば、
バイント・ディレクトリーを RPG ソースの H-仕様書に登録するか、または CRTPGM
のときに
指定すれば、かつてに作成したモジュールを、いくらでも再利用することができる。
現在、米国では 「RPG の近代化」(RPG Modernization
) が話題の中心となっていて
RPG の再エンジニアリングが最も注目されている。
こういった中でサブ・ルーチンではなく、プロシージャーを使うように変更すればカプセル化されて
保守性も高まり、他人が見やすいプログラムとなる。
また、ここで紹介したモジュラー・プログラミングにすればモジュールを再利用することができる。
ただし、*SRVPGM
に比べて *MODULE
の再利用は *MODULE
が変更されたときは、
その *MODULE
をバインドしている *PGM
も再コンパイルの必要があることを注意していて欲しい。
*SRVPGM
にすべきか、どうか判断ができない場合でも *MODULE
を残しておけば再利用率は
高まるのである。
Java が最初に注目されたのは、Java として作成されたオブジェクトは、すべて class という
同じオブジェクトであり、上位のJava から必ず利用することができるという
「オブジェクト指向」であった。
VC++ も、また世界中に広がっている数千万 ... の VC++ のオブジェクトは、すべてたったひとつの
クラスから派生して生成されていると言われている。
これまで RPG が、あまりにも生産性が良く、カンタンに開発することができてしまうので
オブジェクトの再利用の必要性が問われなかったに過ぎない。
しかし企業法人の保有するソフトウェア資産は、いまや莫大な数に登っている。
10 年以上、同じプログラムを動作させているとしたら、安全も大事ではあるが
ソフトウェアの近代化、つまりリエンジアリングが必要な時期にさしかかっていると考えてよいだろう。