【PL/I深掘り】ON ENDFILEでハマらないための「終了処理」の鉄則
メインフレームの現場でPL/Iを触っていると、必ず直面するのが「ストリーム入出力の制御」だ。特にバッチ処理の定番である「ファイル読み込み終了時(ENDFILE条件)のハンドリング」は、シンプルに見えて、実は仕様の勘違いが致命的なループや予期せぬ異常終了を招く温床になる。
今回は、我々エンジニアが保守現場で「なぜかループが抜けない」「終了処理が正しく走らない」と頭を抱えるポイントを整理し、堅牢なコードの書き方を伝授しよう。
—
1. ON ENDFILEの基本と「復帰」の考え方
PL/Iの`ON ENDFILE(ファイル名)`は、単なる終了通知ではない。これは「条件が発生したときに実行される割り込みルーチン」だ。
ここでの最大の落とし穴は、「ONユニットを抜けた後、制御がどこに戻るか」という点にある。基本仕様では、ONユニットの処理が終わると、条件が発生した直後の文(GET文など)の「次の文」に戻ろうとする。だが、ENDFILEが発生した地点で、ファイルは既にEOFに達している。そのまま何も考えずに処理を続行しようとすれば、再びENDFILEを検知し、無限ループに陥るのは火を見るよりも明らかだ。
現場の定石としては、ONユニット内で`GO TO`を使ってループの外へ脱出するか、フラグを立ててメインループ側で制御するのが鉄則だ。
—
2. 実践的なコーディング例
以下に、VSAMやQSAMを扱うバッチ処理で最も安全と言える、フラグ制御を用いた実装パターンを示す。
/i
/——————————————————————-/
/ プログラム名: BATCH01 (メインバッチ処理) /
/ 目的: 入力ファイルを読み込み、終了判定を確実に行う /
/——————————————————————-/
BATCH01: PROCEDURE OPTIONS(MAIN);
DCL INFILE FILE RECORD INPUT; / 入力ファイル定義 /
DCL EOF_FLAG BIT(1) INIT(‘0’B); / 終了判定フラグ /
/ 1. ONユニットの定義:ファイル終了時の挙動を指定 /
ON ENDFILE(INFILE) BEGIN;
EOF_FLAG = ‘1’B; / 終了フラグを立てる /
END;
OPEN FILE(INFILE);
/ 2. メインループ:フラグを監視する /
DO WHILE (EOF_FLAG = ‘0’B);
READ FILE(INFILE) INTO(REC_BUFFER);
/ EOF検知後の再読み込みを防ぐためのガード /
IF EOF_FLAG THEN LEAVE;
/ ここにビジネスロジックを記述 /
CALL PROCESS_DATA(REC_BUFFER);
END;
CLOSE FILE(INFILE);
PUT SKIP LIST(‘BATCH PROCESSING COMPLETED SUCCESSFULLY.’);
END BATCH01;
このコードのポイント
- `EOF_FLAG`による制御: `GO TO`での強引な脱出は、スパゲッティコードの元だ。フラグ管理にすることで、処理の終了ポイントが明確になる。
- `LEAVE`の活用: EOFを検知した直後に、ループの残りの処理をスキップして即座に抜ける。これが一番安全だ。
- `RECORD`入出力の意識: ストリーム入出力(`GET`)ではなく、`READ`を使用している点に注目してほしい。基幹系ではデータの整合性が命であり、レコード単位での制御が推奨される。
—
3. ベテランからのアドバイス:トラブルを避けるために
現場で調査をしていると、`ON ENDFILE`の記述場所が分散しているコードをよく見かける。これらは、保守時に「どのONユニットが有効なのか」を追うのが非常に困難だ。
覚えておくべき3つの掟
1. ONユニットはPROCEDUREの最初の方で宣言せよ
ONユニットは動的だ。呼び出された手続きのスコープ内で定義されるため、宣言場所が不明確だと、意図しない場所で古いONユニットが有効になり、バグの温床となる。
2. `FINISH`条件との併用を検討せよ
ファイルのClose漏れを防ぐなら、`ON FINISH`を使用して、プログラムが正常終了・異常終了にかかわらず、開いているファイルがあればCloseするように組むのがプロの仕事だ。
3. `BUILTIN`関数を侮るな
ファイルの現在状況を確認したい場合は、`STATUS(INFILE)`などの組み込み関数を活用しよう。特にVSAMアクセス時は、`ON CODE`関数で発生した例外コードを確認することで、単なるEOFなのか、それとも物理的なI/Oエラーなのかを即座に切り分けられる。
—
まとめ
PL/IのONユニットは、使いこなせば非常に強力なエラーハンドリングツールになる。しかし、それは「制御フローを書き換える」という強力な武器であることを忘れてはならない。
今日紹介したようなフラグ制御と確実なループ離脱を徹底するだけで、バッチ処理の安定性は格段に向上するはずだ。次の改修時、ぜひ自分のコードを見直してみてほしい。「このループ、本当に安全に抜けられているか?」と。
メインフレームのコードは、先人が残した資産であり、我々の手でそれをより堅牢に磨き上げていくのが責務だ。また何かあればいつでも聞いてくれ。
