導入:なぜデータ共有のルールが重要なのか
COBOLでプログラムを組んでいると、メインプログラムからサブプログラムへデータを渡したり、共通のデータを複数のプログラムで使いたくなったりすることがあります。そんな時、「GLOBAL」や「EXTERNAL」といったキーワードを耳にしますが、これらを適当に使い分けると、思わぬバグの原因になります。特に「両方とも共有のためのものだから、一緒に使えばもっと便利なのでは?」と考えるのは危険です。今回は、この二つの違いと、なぜ同時に使ってはいけないのか、その設計思想を解説します。
基礎知識:GLOBALとEXTERNALの違い
まず、それぞれの役割を整理しましょう。
GLOBAL(グローバル句)
これは「階層」でデータを共有する仕組みです。主に、一つのプログラム内にあるプログラム(ネストされたプログラム)に対して、親プログラムのデータ項目を参照・更新させるために使います。
EXTERNAL(外部属性)
これは「実行単位全体」でデータを共有する仕組みです。バラバラにコンパイルされた複数のプログラム間で、同じ名前のデータ項目を共有したい時に使います。
これらは「共有したい範囲」が全く異なるため、混在させることができないのです。
実装・解決策:スコープの二者択一原則
設計を行う際は、「このデータは誰と誰が共有するものか?」を明確にしましょう。
1. 親子関係で共有するなら GLOBAL:プログラムの中に別のプログラムを記述する「入れ子構造」の場合に適しています。
2. 独立したプログラム間で共有するなら EXTERNAL:別々にコンパイルし、リンクして実行するような大規模なシステムで共通のワークエリアを作る場合に適しています。
どちらか一方を選択するのが、バグを減らすための鉄則です。
サンプルプログラム
ここでは、独立したプログラム間でデータを共有するEXTERNALの例を紹介します。
[PROG-A.CBL]
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG-A.
WORKING-STORAGE SECTION.
- EXTERNALを指定することで、他のプログラムからもアクセス可能にする
01 SHARED-DATA EXTERNAL.
05 USER-ID PIC X(10) VALUE ‘USER001’.
PROCEDURE DIVISION.
DISPLAY ‘PROG-A: ‘ USER-ID.
CALL ‘PROG-B’.
STOP RUN.
[PROG-B.CBL]
IDENTIFICATION DIVISION.
PROGRAM-ID. PROG-B.
WORKING-STORAGE SECTION.
- 親と同じ名前、同じ構造でEXTERNALを指定すると、メモリ上の同じ場所を参照する
01 SHARED-DATA EXTERNAL.
05 USER-ID PIC X(10).
PROCEDURE DIVISION.
- PROG-Aでセットされた値がここでも参照できる
DISPLAY ‘PROG-B: ‘ USER-ID.
EXIT PROGRAM.
応用・注意点:現場で役立つアドバイス
現場でよくある失敗は、EXTERNALを乱用して、どのプログラムがデータを書き換えたのか追跡できなくなるケースです。
注意点:
EXTERNALを使用するデータ項目は、可能な限り「読み取り専用」に近い形で運用するか、更新する責任を持つプログラムを一つに絞る設計にしましょう。GLOBALについても同様で、深い階層でGLOBALを多用すると、どこで値が変更されたか追いかけるのが非常に困難になります。
「共有範囲を最小限にする」ことこそが、ベテランCOBOL技術者が最も大切にしている設計の極意です。ぜひ、プログラムを書く前に「このデータは本当に外部に見せる必要があるか?」を一度自問自答してみてくださいね。

コメント