PL/Iの「DOループ」は怖くない!判定タイミングで変わる運命の分岐点
メインフレームの世界へようこそ。COBOLやJavaでバリバリ開発してきたあなたにとって、PL/Iの構文は一見すると少し「クセが強い」と感じるかもしれませんね。でも安心してください。PL/Iは、非常に論理的で、一度コツを掴めばこれほど頼りになる言語はありません。
今回は、基幹システムのバッチ処理で最も頻繁に登場する「繰り返し処理(ループ)」、その中でも特にミスが起きやすいDO WHILEとDO UNTILの判定タイミングについて、深掘りしていきます。
—
1. そもそもPL/Iのループはどうなっているの?
PL/Iのプログラムは、`PROCEDURE OPTIONS(MAIN)`で始まり、`END;`で終わるのが基本です。この中での繰り返し処理は、まさに「仕事の進め方」そのもの。
- DO WHILE: 「まず条件をチェックして、OKなら仕事する」
- DO UNTIL: 「まず仕事をしてから、最後に条件をチェックする」
この「チェック」のタイミングが、バッチ処理の現場では「初回データがゼロ件のとき、動くのか止まるのか」という決定的な差を生むんです。
—
2. 判定タイミングをコードで比較してみよう
まずは、単純なカウンターを使ったコードで動きを確認しましょう。
1
TEST_LOOP: PROCEDURE OPTIONS(MAIN);
DCL COUNTER FIXED BIN(15) INIT(0);
/ — DO WHILE の例 — /
/ 条件が真(TRUE)の間だけ繰り返す /
DO WHILE (COUNTER > 0);
PUT SKIP LIST(‘DO WHILEが動いた’);
END;
/ — DO UNTIL の例 — /
/ 条件が真になるまで繰り返す(最低1回は実行される) /
DO UNTIL (COUNTER > 0);
PUT SKIP LIST(‘DO UNTILが動いた’);
COUNTER = 1; / ここで初めて条件が満たされる /
END;
END TEST_LOOP;
なぜDO WHILEは「空振り」するのか?
`DO WHILE (COUNTER > 0)` は、ループの入口で門番が待ち構えています。「君、中に入る資格(COUNTER > 0)があるかい?」と聞くわけです。初期値が0なら、「資格がないね」と判断されて、中の処理は一度も実行されずにスルーされます。
なぜDO UNTILは「強制執行」するのか?
一方、`DO UNTIL`は「とりあえず中に入って仕事してから考えよう」というスタンスです。出口で門番が「条件クリアした?」と聞いてきますが、中身は必ず1回実行されてしまいます。もし、ファイルから読み込んだデータが「0件」だった場合、`DO UNTIL`を使うと、「データがないのに処理を実行しようとしてエラー(EOFエラーなど)」を引き起こす引き金になることがあります。
—
3. 実務で「やってしまった!」を防ぐために
現場の保守でよくあるトラブルが、「COBOLのPERFORM UNTILをそのままPL/IのDO UNTILに書き換えたら、バグった」というケースです。
実は、COBOLの`PERFORM UNTIL`はPL/Iの`DO WHILE`に近い動きをします。この「言語間のニュアンスの差」が、メインフレーム移行時の落とし穴なんですね。
賢い使い分けの指針
- DO WHILE: 「入力ファイルがある間だけ処理する」といった、0件の場合に処理をスキップしたいケースに使います。基幹系バッチのメインループは、ほとんどこれです。
- DO UNTIL: 「とりあえず画面を表示して、ユーザーが終了ボタンを押す(終了フラグが立つ)まで繰り返す」といった、最低1回は必ず処理を通したいケースに使います。
—
4. 最後に:恐れずに「デバッグ」という武器を
PL/Iのコンパイラは非常に厳格ですが、その分、プログラムの意図を正確に機械語に翻訳してくれます。
もし「どっちを使うべきか迷った」ときは、「もし対象データが0件だったら、この処理はどうなってほしいか?」を自分に問いかけてみてください。
- 0件でもエラーにならずに終わってほしい → DO WHILE
- 0件でも最低限の初期処理は動いてほしい → DO UNTIL
この視点さえ持っていれば、もう怖くありません。一つずつ、ブロックを積み上げるように理解していけば、あなたも立派なメインフレームアーキテクトの一員です。
また次回の記事では、PL/I特有の「構造体(DECLARE 1 …)」のメモリ配置について深掘りしていきましょう。あれを知ると、基幹システムの見え方がガラリと変わりますよ!それでは、また現場でお会いしましょう。
