現場のエンジニアへ告ぐ:PL/Iの「ON ZERODIVIDE」を使いこなせば、深夜のバッチ異常終了は怖くない
やあ。今日もメインフレームの保守、ご苦労様。
PL/Iという言語は、現代の言語から見れば少し古風に映るかもしれない。だが、この言語には設計思想の端々に「システムを止めない」という強い意志が込められている。特に、異常発生時にプログラムをクラッシュさせるのではなく、制御を奪い返してリカバリを図る「ONユニット」の仕組みは、汎用機開発の真骨頂だ。
今回は、現場で最も遭遇しやすいエラーの一つである「ゼロ除算(ZERODIVIDE)」へのスマートな対処法について、実践的な知見を共有しよう。
—
1. そもそもPL/Iには「予約語」が存在しないという事実
まず基本のおさらいだが、PL/Iにおいて`IF`や`THEN`、`ZERODIVIDE`といったキーワードは「予約語」ではない。これらは「文脈キーワード(Contextual Keywords)」と呼ばれている。
つまり、変数の名前に`ZERODIVIDE`と付けても、コンパイラは文脈からそれを「例外条件」なのか「変数」なのかを判断する。これは非常に柔軟だが、裏を返せば、不用意にキーワードと同じ名前を変数に付けると、可読性を著しく損なうというリスクを孕んでいる。保守を引き継ぐ後輩のためにも、命名規則は厳格に守るのがプロの流儀だ。
2. ONユニットによる「異常の封じ込め」
計算処理の途中でゼロ除算が発生したとき、何も対策をしていなければシステムは即座に異常終了(ABEND U4038など)し、オペレーターが泣くことになる。ここで`ON ZERODIVIDE`の出番だ。
`ON`ユニットは、いわば「エラー発生時の避難訓練」をあらかじめ登録しておく仕組みだ。実行中に条件がトリガーされると、制御がメイン処理からONユニット内へジャンプする。処理が終われば、`REVERT`(無効化)や、必要に応じて`GO TO`で処理を継続させることも可能だ。
3. 実践:安全な除算処理の実装例
VSAMファイルから読み込んだ数値を計算するバッチプログラムを想定してみよう。除数がゼロになる可能性がある場合、以下のように実装するのが「大人のコード」だ。
1
/ ——————————————————— /
/ プログラム名: DIV_CALC_SAMPLE /
/ ゼロ除算をトラップし、異常終了を回避する例 /
/ ——————————————————— /
DIV_CALC_SAMPLE: PROC OPTIONS(MAIN);
DCL DIVIDEND FIXED DEC(10, 2); / 被除数 /
DCL DIVISOR FIXED DEC(10, 2); / 除数 /
DCL RESULT FIXED DEC(10, 2); / 結果 /
DCL ERROR_FLAG BIT(1) INIT(‘0’B);
/ ゼロ除算発生時の処理を定義 /
ON ZERODIVIDE BEGIN;
PUT SKIP LIST(‘警告: ゼロ除算が発生しました。計算をスキップします。’);
ERROR_FLAG = ‘1’B;
END;
/ テスト用データ:除数が0 /
DIVIDEND = 100.00;
DIVISOR = 0.00;
/ 計算実行 /
ERROR_FLAG = ‘0’B;
RESULT = DIVIDEND / DIVISOR;
/ エラーが起きていなければ結果を出力 /
IF ^ERROR_FLAG THEN
PUT SKIP EDIT(‘計算結果:’, RESULT)(A, F(10, 2));
ELSE
PUT SKIP LIST(‘計算は正常に行われませんでした。’);
/ 正常終了 /
RETURN;
END DIV_CALC_SAMPLE;
4. ベテランからのアドバイス:ここが現場の落とし穴だ
コードを見れば分かる通り、`ON`ユニット内ではエラーフラグを立てるだけに留めるのが安全だ。
- GO TOの乱用に注意せよ: `ON`ユニット内で`GO TO`を使用してメイン処理へ無理やり戻ることもできるが、これは「スパゲッティコード」の温床だ。制御フローを複雑にしすぎると、数年後の改修で地獄を見る。
- 例外のスコープ: `ON`ユニットはスタックされる。もしネストされたプロシージャで個別のエラー処理が必要なら、適切に`REVERT`文を使って、不要になったらONユニットを解除する習慣をつけよう。
- BUILTIN関数の活用: 数値のチェックには`DIVIDE`関数や`PRECISION`関数を併用し、そもそもゼロ除算が発生しないようなデータチェックを前段で行うのが、一番の防衛策だ。
結びとして
PL/Iは、古い言語かもしれないが、大規模な基幹システムを支え続けてきただけの「懐の深さ」がある。`ON`ユニットを使いこなすことは、単にバグを防ぐことではなく、システムの堅牢性(レジリエンス)を高めることと同義だ。
現場でエラーログに直面したとき、焦ってソースを書き換えるのではなく、「どの例外条件が拾えるか?」を一度立ち止まって考えてみてほしい。君たちの書く一本のコードが、深夜のシステム運用を救うことになるのだから。
また何か壁にぶつかったら、いつでも聞きに来るといい。健闘を祈る。
