【COBOL学習|豆知識】CALL文の飛び先を動的に!PROCEDURE-POINTERで柔軟なプログラムを構築

導入: なぜPROCEDURE-POINTERが重要なのか

COBOLプログラム開発において、プログラムの実行フローを柔軟に制御したい場面は少なくありません。特に、実行時に呼び出すサブルーチンを決定したり、コールバックのような処理を実現したりする場合、従来のCALL文だけでは記述が複雑になりがちです。

そこで役立つのが、`USAGE IS PROCEDURE-POINTER` です。これは、単なるデータのアドレスではなく、プログラムやメソッドの「入口(エントリポイント)」のアドレスを保持できる特殊なデータ型です。これにより、CALL文の飛び先を動的に変更することが可能になり、より柔軟で拡張性の高いプログラムを構築できるようになります。

基礎知識: PROCEDURE-POINTERとは?

`PROCEDURE-POINTER` は、プログラム内の特定の場所(プロシージャ)を指し示すためのポインタです。具体的には、そのプロシージャが開始されるメモリ上のアドレスを格納します。

  • データポインタとの違い: 一般的なデータポインタは、変数などのデータが格納されているメモリ上のアドレスを指しますが、PROCEDURE-POINTERは、実行可能なコードの開始アドレスを指します。
  • CALL文との連携: `PROCEDURE-POINTER` は、`CALL` 文と組み合わせて使用されます。`CALL` 文の引数として `PROCEDURE-POINTER` 変数を指定することで、そのポインタが指し示すプロシージャを呼び出すことができます。

実装/解決策: PROCEDURE-POINTERの使い方

`USAGE IS PROCEDURE-POINTER` を使用する基本的な手順は以下の通りです。

1. PROCEDURE-POINTER変数の定義: `WORKING-STORAGE SECTION` などで、`PROCEDURE-POINTER` 型の変数を定義します。
2. プロシージャへのポインタの設定: `SET` 文を使用して、呼び出したいプロシージャ(段落やセクション)のアドレスを `PROCEDURE-POINTER` 変数に設定します。
3. 動的なCALL: `CALL` 文で、`PROCEDURE-POINTER` 変数を指定してプロシージャを呼び出します。

サンプルプログラム: 動的なサブルーチン呼び出し

以下のサンプルプログラムは、`PROCEDURE-POINTER` を使用して、実行時に異なるサブルーチンを呼び出す例です。

IDENTIFICATION DIVISION.
PROGRAM-ID. DYNAMICCALL.
DATA DIVISION.
WORKING-STORAGE SECTION.

  • 処理を実行するプロシージャへのポインタを定義

01 WS-PROC-PTR USAGE PROCEDURE-POINTER.
01 WS-CHOICE PIC X(01) VALUE ‘1’.

PROCEDURE DIVISION.
MAIN-PROCEDURE.
DISPLAY “どの処理を実行しますか? (1:Greeting, 2:Farewell)”.
ACCEPT WS-CHOICE.

IF WS-CHOICE = ‘1’ THEN

  • ‘GREETING-PROCEDURE’ のアドレスをポインタに設定

SET WS-PROC-PTR TO ENTRY GREETING-PROCEDURE

  • ポインタが指すプロシージャを呼び出す

CALL WS-PROC-PTR
ELSE IF WS-CHOICE = ‘2’ THEN

  • ‘FAREWELL-PROCEDURE’ のアドレスをポインタに設定

SET WS-PROC-PTR TO ENTRY FAREWELL-PROCEDURE

  • ポインタが指すプロシージャを呼び出す

CALL WS-PROC-PTR
ELSE
DISPLAY “無効な選択です。”
END-IF.

STOP RUN.

  • 挨拶を表示するプロシージャ

GREETING-PROCEDURE SECTION.
DISPLAY “こんにちは!”.
EXIT SECTION.

  • 別れの挨拶を表示するプロシージャ

FAREWELL-PROCEDURE SECTION.
DISPLAY “さようなら!”.
EXIT SECTION.

コードの解説:

  • `WS-PROC-PTR USAGE PROCEDURE-POINTER.` : プロシージャへのポインタを格納する変数を定義します。
  • `SET WS-PROC-PTR TO ENTRY GREETING-PROCEDURE` : `ENTRY` キーワードを使用し、`GREETING-PROCEDURE` という名前のプロシージャ(ここではセクション)のエントリポイントアドレスを `WS-PROC-PTR` に設定します。
  • `CALL WS-PROC-PTR` : `WS-PROC-PTR` が指し示すプロシージャを呼び出します。

応用・注意点: 現場で役立つ補足情報

  • ENTRY句の重要性: `SET` 文でプロシージャのアドレスを設定する際には、`ENTRY` キーワードが必須です。これにより、コンパイラは対象をプロシージャのエントリポイントとして認識します。
  • 引数の受け渡し: `PROCEDURE-POINTER` を使用して呼び出すプロシージャに引数を渡すことも可能です。その場合、`PROCEDURE-POINTER` 変数に設定するプロシージャは、`CALL` 文で指定する引数リストと互換性がある必要があります。
  • NULLチェック: `PROCEDURE-POINTER` 変数が有効なアドレスを指しているかどうかのチェックは、エラー回避のために重要です。ただし、COBOLの標準機能では直接的なNULLチェックの方法が限られているため、プログラム設計で工夫が必要です。例えば、初期化時に特定の値(例えば、有効なプロシージャのアドレスではないことを示す値)を設定しておき、呼び出し前にその値と比較するなどの方法が考えられます。
  • コールバック関数: 外部ライブラリや他のプログラムから、自作のCOBOLルーチンを呼び出したい(コールバックさせたい)場合にも `PROCEDURE-POINTER` が活用できます。

`USAGE IS PROCEDURE-POINTER` を使いこなすことで、COBOLプログラムの保守性や拡張性を大きく向上させることができます。ぜひ、日々の開発で活用してみてください。

コメント

タイトルとURLをコピーしました