【実務・中級編】DO WHILEとDO UNTILの判定タイミングの差異 – PL/Iの基本構文とデータ制御実践ガイド

【PL/I深掘り】DO WHILEとDO UNTIL:ループの「判定タイミング」がバッチ処理にもたらす破壊的影響

現場の皆さん、お疲れ様です。アーキテクトの私です。

今日は、PL/Iでシステム開発や保守を長くやっていると、誰しも一度は「痛い目」を見る、ループ制御の話をしよう。特にオンラインや巨大なバッチ処理で、DO WHILEとDO UNTILの使い分けを誤り、特定の条件下でレコードが飛ばされたり、逆に意図しないループに陥ったりした経験はないだろうか?

「そんなの常識だろう」と思うかもしれないが、数百万レコードを扱うVSAM処理の最中にこの判定タイミングのズレが混入すると、リカバリには地獄を見る。今日は、その論理的差異を現場の視点で整理する。

1. 判定タイミングの「決定的な違い」

まず、基本のおさらいだが、単なる仕様の丸暗記では不十分だ。

  • DO WHILE: 「入る前」に判定する。ガード条件が満たされなければ、中身は一度も実行されない。
  • DO UNTIL: 「出た後」に判定する。最低でも一度は確実に実行される。

この差が、メインフレーム上のバッチ処理でなぜ重要か。それは、「最初の1件(あるいはフラグ)」が、外部からの入力か、ループ内の処理結果かによって、どちらを選ぶべきかが決まるからだ。

2. 実践コード:VSAMファイル読込での比較

VSAMからレコードを読み込み、フラグが立つまで処理を続ける典型的なケースを見てみよう。

/i
/ — DO WHILEを用いたガード付き処理 — /
/ 最初のREADをループ前に行い、成功した場合のみループに入る /
READ FILE(VSAM-IN) INTO(REC-AREA);
DO WHILE(EOF-FLG = ‘0’);
/ 処理ロジック /
CALL PROCESS-RECORD(REC-AREA);

READ FILE(VSAM-IN) INTO(REC-AREA);
END;

/ — DO UNTILを用いた最低1回保証の処理 — /
/ 最初のREADからループ内で完結させたい場合 /
DO UNTIL(EOF-FLG = ‘1’);
READ FILE(VSAM-IN) INTO(REC-AREA);
IF EOF-FLG = ‘0’ THEN DO;
CALL PROCESS-RECORD(REC-AREA);
END;
END;

なぜDO WHILEの方が「安全」と言われるのか?

現場のバッチ改修で私がDO WHILEを好む理由は、「空ファイル(EOF)」に対する耐性だ。

DO UNTILは構造上、条件チェックがループの最後にあるため、ファイルが空であっても「1回は読み込み処理」が走る。この時、誤ってEOF判定を怠ると、存在しないレコードを処理しようとしてON ENDFILEが発火したり、予期せぬアベンド(S0C4やS0C7など)を誘発する温床になる。

3. ONユニットとの組み合わせに潜む罠

PL/Iの強力な機能である`ON ENDFILE`を併用する場合、DO UNTILを使うとフローが非常に読みづらくなる。

/i
ON ENDFILE(VSAM-IN) EOF-FLG = ‘1’;

/ DO UNTILの場合、ENDFILEが発生した瞬間、 /
/ ループ中のコードがどこまで実行されるかの制御が複雑化する /
DO UNTIL(EOF-FLG = ‘1’);
READ FILE(VSAM-IN) INTO(REC-AREA);
/ EOFフラグが立った後、この下の処理はどうなる? /
/ 判定が後ろにあるため、フラグを考慮したIF分岐が不可欠になる /
END;

大規模な基幹システムでは、可読性と保守性が命だ。「一度も実行されない可能性がある」なら迷わずDO WHILE。逆に「どんな状況でも必ず一度は実行し、その結果でループを継続するか決める(例:ユーザー入力待ちや、特定の計算反復)」ならDO UNTIL。

この原則を守るだけで、バグの温床は確実に減る。

4. 現場のアーキテクトからのアドバイス

最後に一つ、教訓を伝えておく。

「コードの行数を減らそうとして、無理やりDO UNTILに詰め込まないこと」。

DO WHILEで外にREADを出すと行数は増えるが、それは「ガード」という名の安心を買っているのと同じだ。デバッグ時にブレークポイントを貼る際も、DO WHILEなら「ループに入る前」か「ループ内」か明確に区別できる。

PL/Iは古い言語と言われるが、その論理構造は現代の高級言語よりも遥かに厳格で、意図が明確に反映される設計になっている。この「厳格さ」を味方につければ、どんなに複雑なレガシーコードの改修でも恐れることはない。

次回の改修作業では、ぜひループの「入り口」と「出口」の判定タイミングに意識を向けてみてほしい。それができるようになった時、君も一人前のPL/Iエンジニアだ。

それでは、また現場で会おう。

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