【実務・中級編】ON ZERODIVIDEによるゼロ除算例外のハンドリング – PL/Iの基本構文とデータ制御実践ガイド

ゼロ除算を恐れるな ― PL/IのONユニットによる例外制御の流儀

現場の若手エンジニアから、「バッチ処理で計算エラーが起きてシステム異常終了(ABEND)したのだが、どうにかスマートに回避できないか」と相談を受けることがよくある。メインフレームの基幹バッチにおいて、計算結果の分母がゼロになることは、データ品質の劣化や予期せぬ外部インターフェースの変動によって起こり得る「あるある」だ。

PL/Iには、こうした算術例外をエレガントに捌くための強力な武器がある。それが`ON ZERODIVIDE`ユニットだ。今回は、ただの文法解説ではなく、長年の大規模改修の現場で培った「PL/Iらしい」例外ハンドリングの作法を伝授しよう。

1. PL/Iに予約語がないという「自由」と「責任」

まず前提として、PL/Iには明確な「予約語」という概念が存在しない。`IF`や`THEN`、`ON`といったキーワードですら、文脈によっては変数名として宣言できてしまう。これは非常に強力だが、裏を返せば「書き手の規律」がコードの品質に直結するということだ。

識別子の命名やコーディング規約において、キーワードを避けるのは当然として、`ON`ユニットを記述する際は、そのスコープがどこまで及ぶかを常に意識しなければならない。

2. ON ZERODIVIDEによる例外ハンドリングの真髄

`ON ZERODIVIDE`は、実行時にゼロ除算が発生した瞬間に制御を奪い取る。これを使う最大のメリットは、メインのビジネスロジックと、異常発生時のリカバリ処理(あるいはログ出力)を完全に分離できる点にある。

以下のコードを見てほしい。VSAMファイルから読み込んだデータを計算する典型的なパターンだ。

/i
/ — 計算処理用メインプロシージャ — /
CALC_PROC: PROC;

DCL DIVIDEND FIXED DEC(15,2); / 被除数 /
DCL DIVISOR FIXED DEC(15,2); / 除数 /
DCL RESULT FIXED DEC(15,2);

/ ゼロ除算発生時のハンドラを定義 /
ON ZERODIVIDE
BEGIN;
PUT SKIP LIST(‘!!! ゼロ除算を検知しました。計算をスキップします。’);
/ ここでフラグを立てるか、あるいはエラーログを出力 /
RESULT = 0;
/ GOTOを使って計算後の処理へ飛ばすのが定石 /
GOTO CALC_END;
END;

/ 計算実行部 /
RESULT = DIVIDEND / DIVISOR;

CALC_END:
/ 計算結果を用いたVSAM更新処理などへ続く /
PUT SKIP LIST(‘計算結果は: ‘ || TRIM(RESULT));

END CALC_PROC;

3. スタックの巻き戻しと制御フローの罠

ここで注意すべきは、`ON`ユニットがどのように制御を戻すかという挙動だ。

  • REVERTの考え方: `ON`ユニットはスタックに積まれる。ブロックを抜ければ自動的に解除されるが、`REVERT ZERODIVIDE;` を明示的に呼び出すことで、特定の区間だけハンドリングを無効化することも可能だ。
  • GOTOの推奨: 上記の例で `GOTO` を使ったのは、ゼロ除算が発生した地点で「残りの計算処理を無視して次のステップへ進む」のが、バッチ処理における最も安全なフォールバックだからだ。`ON`ユニット内で処理を終えて制御を戻すと、例外が発生した演算命令の直後から再開しようとするため、同じ場所で無限ループに陥るか、不確定な値で計算が継続するリスクがある。

4. 現場のシニアからの一言:デバッグと保守性

現場の保守において、`ON`ユニットは「魔法の杖」ではない。あまりに広範囲に`ON`ユニットを記述すると、バグがどこで発生したのか突き止めるのが非常に困難になる。

  • スコープを最小限に: `BEGIN; … END;` ブロックで囲み、特定の演算処理の直前で有効化するのが鉄則だ。
  • ログ出力の徹底: `ON`ユニットの中では、必ず「なぜゼロになったのか」を特定できるようなキー項目やレコード情報をログに出力するようにせよ。
  • BUILTIN関数の活用: `FIXEDOVERFLOW`や`SIZE`といった他の条件と組み合わせる場合も多いが、まずは`ZERODIVIDE`を確実に制御できるようになることが、安定稼働への第一歩だ。

メインフレームのバッチ開発では、「止まらないこと」が至上命題だ。しかし、それは「泥臭くABENDを隠蔽する」ことではない。PL/Iの仕様を理解し、計算フローを制御下に置くことで、初めて「強固な基幹システム」は完成する。

次回の改修では、`ON`ユニットを活用して、スマートでタフなエラーハンドリングを実装してほしい。何かあればいつでも相談に乗る。コードは嘘をつかない、しっかり向き合おう。

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