1. 導入:引数のバケツリレーに疲れていませんか?
COBOLの開発現場では、メインのプログラムから子プログラムを呼び出す際、CALL文の「USING」句を使ってデータを渡すのが基本です。しかし、プログラムの階層が深くなると、孫やひ孫のプログラムにまでデータを渡すために、中間にあるプログラムが「ただデータを右から左へ流すだけ」という無駄な作業が発生しがちです。
そんな時、EXTERNAL句を使えば、プログラム間で直接アクセス可能な「共通のデータ領域」を作ることができます。いわば、プログラム同士の間に設置する「共有の掲示板」のようなものです。これを使えば、引数のバケツリレーを解消し、設計を劇的にシンプルにできる可能性があります。
2. 基礎知識:EXTERNAL句とは何か?
EXTERNAL句は、その名の通り「外部から参照可能」なデータ項目を定義するためのものです。
通常、COBOLのデータ項目は、定義されたプログラムの中でしか生きられません。しかし、EXTERNALを指定すると、そのデータ項目は実行単位(Run-Unit)全体で共有されるメモリ領域に配置されます。
・実行単位(Run-Unit): 一連の処理として実行されるプログラムの集まりです。
・グローバルなデータ: プログラムAで値をセットすれば、CALLされたプログラムBが、引数なしでその値を取得できます。
3. 実装と解決策
実装は非常に簡単です。共有したいデータ項目に「EXTERNAL」というキーワードを追加するだけです。ただし、注意点があります。共有する側とアクセスする側の両方で、全く同じデータ名と構造(PIC句など)を定義しなければなりません。
もし構造が一致していないと、メモリの読み込み位置がズレてしまい、思わぬバグ(文字化けや意図しない数値の混入)を引き起こします。これを防ぐために、現場では「COPY句」を使って、同じ定義ファイルを双方で読み込むのが鉄則です。
4. サンプルプログラム
以下のコードは、メインプログラムで設定した値を、子プログラムで受け取る例です。
[メインプログラム側]
01 COMMON-DATA EXTERNAL.
05 USER-ID PIC X(10).
05 STATUS-CODE PIC 9(02).
- メインプログラムでの処理
MOVE “TARO001” TO USER-ID.
MOVE 01 TO STATUS-CODE.
CALL “SUB-PROG”.
[子プログラム側]
01 COMMON-DATA EXTERNAL.
05 USER-ID PIC X(10).
05 STATUS-CODE PIC 9(02).
- 子プログラムでの処理
- 引数を使わなくても、メインでセットした値がここにある
DISPLAY “受け取ったユーザーIDは: ” USER-ID.
DISPLAY “ステータスは: ” STATUS-CODE.
5. 応用・注意点:設計上の心得
便利なEXTERNAL句ですが、乱用は禁物です。以下の点には十分注意してください。
・再入可能性(Reentrancy)への影響:
EXTERNALを使用すると、プログラムが状態を持つようになります。複数のスレッドや多重呼び出しを行う環境では、予期せぬタイミングでデータが書き換えられるリスクがあります。
・追跡の難しさ:
どこで値が書き換わったのかをデバッグする際、引数渡しと違って「プログラム全体のどこからでもアクセスできる」ため、犯人探しが難しくなることがあります。
結論として、EXTERNALは「頻繁に参照するが、書き換えが少ない共通情報(システム日付や環境設定値など)」に限定して使うのが、ベテランの設計術です。まずは小規模な共有から試してみてください。

コメント