ILE-RPGで開発しているとサブ・ルーチンとプロシージャーは
良く似ているがどちらを使うべきか迷ったことはないだろうか?
_
■ 実行スタックが異なる
基本的にサブ・ルーチンはメイン・ルーチンの一部であり
同じブログラム・スタックの一部として実行される。
これに対してプロシージャーとは別のスタックとして
実行されるのでプロシージャーでエラーが発生すると
エラー・メッセージにはどのプロシージャーで
エラーになったのかをエラー・メッセージで表示されるので
エラー発生のときの原因の追究にも早くなる。
■ ローカル変数とグローバル変数
サブ・ルーチンはメイン・ルーチンの一部にしか過ぎないので
サブ・ルーチンが使用する変数もメイン・ルーチンの変数とは
同じものを共有して使用することになる。
サブ・ルーチンを使い慣れている開発者はこれは当たり前のこととして
思うかもしれないがプログラムのバグの便印が
デバッグで追いかけていくと実はサブ・ルーチンの中で
変数が書き換えられていたというトラブルを経験したことはないだろうか?
例えば配列指標 N を使ってメイン・ルーチンで LOOPをしているときに
サブ・ルーチンの中でも同じ変数 N を使ったために Nが書き換えられて
しまってバグるという具合である。
_
これに対してプロシージャーではプロシージャーの中だけで有効になる
ローカル変数を定義してメイン・ルーチンとの変数の重なりを防ぐことができる。
メイン・ルーチンで定義した変数はグローバル変数と呼ばれて
プロシージャーでも使用することができる。
しかし一般にはプロシージャーで使う作業変数はプロシージャー内だけで
ローカル変数として定義することが一般的である。
プロシージャーはサブ・ルーチンと違ってプロシージャーだけで完結するように
記述すべきである。
■ オブジェクトの再利用
ここからがサブ・ルーチンとプロシージャーの決定的な違いである。
サブ・ルーチンで社内で共通して使えるビジネス・ロジックがあったとする。
毎回、同じサブ・ルーチンをあちこちの社内プログラムに記述するような
ことはしないだろう。
そのサブ・ルーチンのビジネス・ロジックが社内制度を示すものであったら
社内制度が変更したらすべてのサブ・ルーチンを書き換えなければならない。
たとえ /COPY でソースを共有させたとしても漏れなく再コンパイルする必要がある。
このようなときにプロシージャーにしておけばそのプロシージャーの部分だけを
オブジェクトとして公開して他のプログラムで再利用することができるのである。
制度が変わっても元のプロシージャーを変更するだけでよい。
それを利用しているプログラムを再コンパイルする必要はない。
あるプログラムを開発したとする。そのプログラムは単独で動作するのだが
そのプログラムに使われているプロシージャーだけを公開して
他のプログラムからこれを参照して利用することがむできる。
これこそがオブジェクト指向ということである。
機能 | サブ・ルーチン | プロシージャー |
---|---|---|
PGMスタック | メイン・ルーチンの一部 | 別のスタックとして独立 |
変数 | メイン・ルーチンと共通 | ローカル変数とグローバル変数 |
公開(EXPORT) | ソース・レベルの公開 | オブジェクトを公開可能 |
[注意]
プロシージャーの中でサブ・ルーチンを定義したとするとそのサブ・ルーチンはローカルであるので
メイン・ルーチンや他のプロシージャーから呼び出すことはできない。
他のプロシージャーでも使えるようにしたいのであればそのサブ・ルーチンも別の独立した
プロシージャーとして定義すべきである。
実はIBM OS のRPGやCOBOLの命令はプロシージャーである。
いつも使っているSETLLやCHAIN命令もOSの中ではプロシージャーとして定義されている。
あなたの会社では IBM iを買い換えたときにすべてのプログラムを再コンパイルしてください
とIBM に言われたことはないはずである。
_
これはプロシージャーであるからこそできることである。
しかしソフトウェア会社がILEを良く理解していないで作った製品は
製品の障害があったりリリース・アップするとユーザーが開発したプログラムをすべて
再コンパイルしなければならないという悲惨な事態になる場合がある。
このため全くPTFを発行しないソフト製品開発会社もある。
この製品のユーザーはPTFも無いままにただ何の変更もないのに
保守料を払っているだけである。
弊社の製品はもちろんPTFを配布してもお客さまに再コンパイルをお願いすることはない。