【PL/I深掘り】ON ENDFILEはなぜ「GOTO」で抜けるのが正解なのか? 現場で語り継ぐファイル制御の極意
メインフレームの現場で、若いエンジニアからよくこんな質問を受ける。「なぜPL/IのON ENDFILEでは、わざわざGOTOを使うんですか? 構造化プログラミングの観点からすると、あまり行儀が良くない気がするのですが」。
その疑問はもっともだ。だが、メインフレームのバッチ処理、特に数百万件のレコードを処理する基幹系システムにおいて、PL/IのONユニットは単なる「エラーハンドリング」ではなく、「制御フローの重要な一部」として機能している。今日は、この仕様を正しく理解し、現場で迷わないための「正しい作法」を伝授しよう。
1. ON ENDFILE:イベント駆動型という発想
PL/Iのファイル入出力において、`ENDFILE`条件はコンパイラが「ファイルの終わり」を検知した瞬間に発生する。ここで重要なのは、この条件が発生した瞬間、制御はメインルーチンからONユニットのブロックへ強制的に移るという点だ。
多くの初心者が陥る罠は、ONユニットの中でフラグを立ててメインルーチンに戻り、次の `READ` を実行しようとすることだ。しかし、これでは `READ` 文の後の処理がまだ残っている場合に、誤ったデータ処理を走らせてしまうリスクがある。
2. 実践的なコーディング・パターン
まずは、現場で標準的に使われる「GOTOによる脱出」のコード例を見てほしい。
/i
/—————————————————————–/
/ 順次ファイル読み込みの標準的な実装パターン /
/—————————————————————–/
TEST_BATCH: PROCEDURE OPTIONS(MAIN);
DCL IN_FILE FILE RECORD SEQUENTIAL INPUT;
DCL EOF_FLAG BIT(1) INIT(‘0’B);
DCL 1 REC_DATA,
5 KEY_FLD CHAR(5),
5 DATA_FLD CHAR(50);
/ EOF検知時のONユニット定義 /
ON ENDFILE(IN_FILE) BEGIN;
EOF_FLAG = ‘1’B;
GOTO LEAVE_LOOP; / ループから強制脱出させるのが定石 /
END;
OPEN FILE(IN_FILE);
DO WHILE(‘1’B);
READ FILE(IN_FILE) INTO(REC_DATA);
/ 読み込み成功後の処理 /
PUT SKIP LIST(‘処理中: ‘ || REC_DATA.KEY_FLD);
END;
LEAVE_LOOP:
CLOSE FILE(IN_FILE);
PUT SKIP LIST(‘処理終了:全レコードを読み込みました。’);
END TEST_BATCH;
3. なぜ「GOTO」が選ばれるのか
なぜ `GOTO` を使うのか。理由はシンプルで、「ONユニット内からメインの処理フローを安全に打ち切り、正常な終了処理(CLOSEや後処理)へ誘導するため」だ。
もし `GOTO` を使わずに抜けた場合、制御は `READ` 文の直後に戻る。しかし、レコードが読み込めていない状態(EOF後)で後続の処理(例えば計算処理やデータ変換)を実行しようとすると、プログラムは予期せぬ挙動を引き起こす。
また、`SIGNAL ENDFILE(IN_FILE)` を使って手動で条件を発生させるテクニックもあるが、これは特定の例外ケースを除き、基本的にはコンパイラに検知させるのが最も確実だ。
4. 現場で生き残るための「鉄則」
現場の保守でトラブルを起こさないために、以下の3点を意識してほしい。
- ONユニットのスコープに注意せよ:
`ON` ユニットは記述したブロック内だけでなく、動的に呼び出された先でも有効な場合がある。特定のファイルに対して確実に動作させたい場合は、ファイルオープン直後に `ON` を定義する癖をつけよう。
- SIGNAL文は「意図」を明確に:
テストデータ作成時や、強制的に終了処理へ飛ばしたい場合に `SIGNAL` は便利だが、デバッグを複雑にする原因にもなる。使用した場合は必ずソースに「なぜここで強制終了させたのか」の意図をコメントで残すこと。
- VSAMアクセスの場合は別物と考える:
今回は順次ファイルの話だが、VSAM(KSDSなど)の場合は `ENDFILE` だけでなく `KEY` や `RECORD` 条件も絡んでくる。VSAMを使う際は、`ON` ユニットだけで制御せず、戻り値(`STATUS` ビルトイン関数)を併用するのがプロの流儀だ。
結びとして
PL/Iという言語は、古臭いようでいて、実はマシンの動作原理を極めて忠実に反映している。`ON ENDFILE` は、単なる命令ではなく、OSとコンパイラが対話している場所だ。
「なぜこう書くのか」を突き詰めていけば、メインフレームのブラックボックス化しているコードも、必ず意味を持って見えてくるはずだ。大規模改修の荒波の中でも、この「確実な制御」という基本を忘れないでほしい。
さて、次はVSAMのSTATUSコードと組み合わせた高度なエラーハンドリングについて話すとしようか。また現場で会おう。
