ネストされたプログラムの呼び出し

ネストされたプログラムを使うと、アプリケーションのためのモジュラー関数を作成し、 構造化プログラミングの技法を維持することができます。 ネストされたプログラムによって、 それぞれ独自の管理範囲の複数の独立した機能を 1 つのコンパイル単位の中で定義することができます。 それらの機能は、PERFORM プロシージャーにローカル・データ項目を保護する機能を加えたものとして使用することができます。

ネストされたプログラムは、コンパイル時には呼び出し側プログラムと同じモジュールに含まれています。 したがって、ネストされたプログラムは、常に呼び出し側プログラムと同じ活動化グループで実行されます。

ネストされたプログラムの構造

ILE COBOL プログラムには、他の ILE COBOL プログラムを含めることができます。 含まれているプログラムにも、他のプログラムが含まれている場合もあります。 含まれているプログラムは、他のプログラムに直接に含まれている場合と、間接に含まれている場合があります。

図 51 に、直接または間接に含まれている、ネストされたプログラムの構造を示します。

図 51. 直接または間接に含まれているプログラムのネスト構造
ネストされたプログラムの図

ネスト・プログラム構造の使用についての規則

ネスト・プログラム構造を使用するときには、適用すべきいくつかの規則があります。

  1. 各プログラムには、見出し部が必要です。 それ以外の部の指定は、すべてオプショナルです。
  2. PROGRAM-ID 段落のプログラム名は、固有でなければなりません。
  3. ネストされたプログラムの名前は、有効な COBOL 語または数値リテラルにすることができます。
  4. ネストされたプログラムに構成セクションを含めることはできません。 構成セクションのオプションが必要なら、それは最も外側のプログラムで指定しなければなりません。
  5. ネストされたプログラムは、そのプログラムを含んでいるプログラムの中の END PROGRAM ヘッダーの直前に含められます (図 51 を参照)。
  6. 各 ILE COBOL プログラムは、END PROGRAM ヘッダーで終了しなければなりません。
  7. ネストされたプログラムの呼び出しまたは取り消しは、同じモジュール・オブジェクトの ILE COBOL プログラムからしか実行できません。
  8. ネストされたプログラムの呼び出しは、CALL リテラル または CALL id ステートメントのどちらかを使用することによってしか実行できません。 ネストされたプログラムの呼び出しは、CALL プロシージャー・ポインター を使用して実行することはできません。 ネストされたプログラムの呼び出しが従う規則は、静的プロシージャー呼び出しの場合と同じです。

ネストされたプログラムの呼び出し階層

ネストされたプログラムは、PROGRAM-ID 段落で COMMON として指定されているのでなければ、 それを直接含むプログラムからしか呼び出せません。 この場合、COMMON プログラムも、その COMMON プログラムを直接含んでいるプログラム内に (直接または間接に) 含まれているプログラムから呼び出すことができます。 再帰呼び出しは、RECURSIVE 文節をもつネストされたプログラム の場合、あるいはネストされたプログラムを直接または間接的に含んでいるプログラムが RECURSIVE 文節 をもっている場合にだけ可能です

図 52 に、COMMON として識別されている、いくつかの含まれたプログラムがあるネスト構造の概要を示します。

図 52. 直接または間接に含まれているプログラムのネスト構造
ネストされたプログラムの図

図 52 に示されている構造の呼び出し階層について、次の表で説明します。 A12、A2、および A3 は COMMON として指定されており、それと関連する呼び出しの結果の相違に注目してください。

表 11. COMMON プログラムを含むネスト構造の呼び出し階層
プログラム 呼び出すことができる プログラム 呼び出される可能性のあるプログラム
A A1、A2、A3 なし
A1 A11、A12、A2、A3 A
A11 A111、A12、A2、A3 A1
A111 A12、A2、A3 A11
A12 A2、A3 A1、A11、A111
A2 A3 A、A1、A11、A111、A12、A3
A3 A2 A、A1、A11、A111、A12、A2

次のことに注意してください。

ネスト構造内の名前の有効範囲

ネスト構造内の名前には、ローカルグローバルという 2 つクラスがあります。 このクラスは、名前を宣言したプログラムの有効範囲以外の場所で名前が識別されるかどうかを決めるものとなります。

ローカル名

GLOBAL と宣言しない限り、名前は必ずローカルになります (プログラム名を除く)。 それらのローカル名は、それを宣言したプログラム以外からは見えず、アクセスできません。 このことは、含んでいるプログラムと含まれているプログラムの両方に当てはまります。

グローバル名

GLOBAL 文節を使用してグローバルとして指定された名前は、 それを宣言したプログラムとそのプログラムに直接または間接に含まれているすべてのプログラムから見え、アクセスすることができます。 これにより、含まれているプログラムは、それを含んでいるプログラムから項目の名前を参照するだけで、 共通のデータとファイルを共用することができます。

グローバル項目に従属する項目 (条件名と指標を含む) は、自動的にグローバルになります。

異なるプログラムでそれぞれの宣言を行う場合は、GLOBAL 文節を使って同じ名前を何度も宣言することができます。 ネスト構造内の名前は、同一の包含構造のうちの異なるプログラムで同じ名前を使用することによって、 マスキングされてしまう (隠されてしまう) ことがあるので注意してください。

名前宣言の検索

プログラム内で名前が参照されると、その名前の宣言の検索が行われます。 検索は、まず参照を含むプログラム内で行われ、次にそれを含む外側のプログラムに向かって、 一致が検出されるまで続行されます。 検索は、次の順序で行われます。

  1. そのプログラム内の宣言が最初に検索されます。
  2. 一致が検出されない場合、それを含む外側のプログラム内のグローバル宣言だけが、外側へ向かって順に検索されます。
  3. 一致する最初の名前が検出された時点で検索は終了します。 一致が検出されない場合は、エラーが存在します。