【テクニカル・上級編】ON ENDFILE条件によるファイル読み込み終了の制御 – PL/Iの基本構文とデータ制御実践ガイド

順次ファイル読み込みの「深淵」— ON ENDFILEと現代的マイグレーションの境界線

メインフレームのバッチ処理において、`ON ENDFILE` は単なる「ファイルの終わり」を告げる合図ではない。それは、基幹システムの心臓部が正しく鼓動を止めるための、極めて重要な制御点だ。

多くのモダン言語(JavaやC#)に慣れ親しんだエンジニアが、PL/Iの `ON ENDFILE` を見ると、「なぜループの途中で制御を飛ばすような非構造的な書き方をするのか」と首を傾げる。だが、ここには汎用機特有の「例外処理とハードウェア割込みの密接な関係」という、歴史的かつ合理的な理由が存在する。

1. ON ENDFILEの定石と「フラグ制御」の哲学

まずは、現場で最も安定稼働するパターンのコードを見てほしい。

/i
/ ファイル読み込みの基本構造 /
MAIN_PROC: PROCEDURE OPTIONS(MAIN);

DCL EOF_FLAG BIT(1) INIT(‘0’B);
DCL IN_REC CHAR(80);

/ ONユニットの設定:ENDFILE発生時にフラグを立てる /
ON ENDFILE(SYSIN) BEGIN;
EOF_FLAG = ‘1’B;
END;

OPEN FILE(SYSIN) INPUT;

/ 読み込みループ /
READ FILE(SYSIN) INTO(IN_REC);
DO WHILE(^EOF_FLAG);
/ ここでビジネスロジックを実行 /
CALL PROCESS_DATA(IN_REC);

READ FILE(SYSIN) INTO(IN_REC);
END;

CLOSE FILE(SYSIN);
END MAIN_PROC;

このコードの肝は、`ON` ユニット内で `EOF_FLAG` をセットし、ループの判定式でそれを評価している点だ。この「フラグ方式」は、`GO TO` を使ってループを強制脱出する手法よりも、スタックの整合性やコードの可読性の面で圧倒的に勝る。

2. アーキテクトの視点:なぜこれが移行の「地雷」となるのか

JavaやC#への移行を検討する際、この `ON ENDFILE` は単なる `while (reader.hasNext())` への置換では済まないことが多々ある。

  • アベンド(ABEND)の再定義: PL/Iではファイル読み込みエラーや予期せぬIO条件が `ON` ユニットによって捕捉されるが、移行先では単なる `IOException` としてスローされる。この「何をもって異常終了(アベンド)とみなすか」の定義のズレが、夜間バッチのリカバリ設計を根底から揺るがす。
  • パックデシマル(PIC S9(n) COMP-3)の罠: 読み込んだデータに不正なパックデシマル(内部符号の反転や無効なゾーンビット)が含まれていた場合、PL/Iは即座に `SOC7` を吐く。だが、移行先のJavaコードでは、数値変換ライブラリが例外を投げずにゼロサプレスやデフォルト値で処理してしまう場合がある。この「データのゴミを許容してしまう」設計は、基幹システムの整合性を致命的に破壊する。

3. 動的メモリとポインタ:最適化の代償

`DCL PTR POINTER;` を多用するような旧来のコードは、メモリ管理の柔軟性と引き換えに、コンパイラ最適化の恩恵を受けにくい。

特に `OPTIMIZE(3)` を指定してコンパイルする場合、コンパイラはレジスタをフル活用してコードを再配置する。このとき、ポインタ経由で間接的にメモリを操作していると、コンパイラが「このメモリ領域は他から変更されない」と誤判定し、デバッグ時に信じられないような動作をすることがある。

もし現在、複雑な動的ストレージを運用しているなら、移行前に一度 `LIST` や `MAP` オプションでコンパイラリストを出力し、メモリマップを徹底的に洗い出すことを強く勧める。

4. 最後に:移行担当者への提言

IBMメインフレームのコードを読み解く際、単なる「構文の翻訳」に終始してはならない。

  • CICSオンライン処理の場合: `ON ENDFILE` はトランザクションの終了条件と複雑に絡み合う。`HANDLE CONDITION` との競合を確認せよ。
  • DB2埋め込みSQLの場合: `SQLCODE` のチェックと `ENDFILE` のチェックを混在させると、デッドロック発生時にどちらが優先されるかという、非常に難解なレースコンディションが待っている。

PL/Iは、ハードウェアの挙動を直接制御できる最後の「高水準言語」だ。そのシンプルに見える `ON` ユニットには、数十年の運用で培われたエラーハンドリングの知恵が詰まっている。移行先の言語でそれを再現する際は、単なる機能置換ではなく、「なぜその例外処理が必要だったのか」という設計思想そのものを再構築してほしい。

それが、レガシーを「負債」ではなく「資産」として次世代へ引き継ぐ、我々アーキテクトの矜持である。

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