こんにちは!メインフレームの世界へようこそ。
COBOLやJavaでバリバリ開発してきたエンジニアの方にとって、PL/Iという言語は少し「古めかしく、かつ謎めいた」存在に見えるかもしれませんね。でも安心してください。PL/Iは、C言語のような柔軟性とCOBOLの堅牢なデータ処理能力を併せ持つ、非常に「人間味のある」言語なんです。
今日は、メインフレームの現場で避けては通れない、でも怖がる必要なんてまったくない「ゼロ除算(ZERODIVIDE)」への対策について、一緒に紐解いていきましょう。
—
そもそもPL/Iのプログラムって何?
まず、PL/Iの基本構造からさらっとおさらいしましょう。PL/Iは「パッケージ」や「プロシージャ」という単位でコードをまとめます。
1
/ プログラムの始まり。これがエントリーポイント(メイン処理)です /
MY_PROGRAM: PROCEDURE OPTIONS(MAIN);
/ ここに変数宣言や処理を書きます /
END MY_PROGRAM;
COBOLに慣れていると「DIVISION」や「SECTION」がないことに驚くかもしれませんね。PL/Iはもっと自由で、PROCEDURE(手続き)の中にすべてを詰め込めるんです。
—
ゼロ除算の悪夢…システムを落とさないために
さて、本題です。計算処理中に「割る数」がゼロになってしまったらどうなるでしょうか?
Javaなら `ArithmeticException` が飛んできてキャッチできますよね。メインフレームのPL/Iも同じです。何も対策をしないと、システムは「ABEND(異常終了)」という、いわば「強制終了」を起こしてしまいます。夜間バッチでこれが起きると、オペレーターさんに叩き起こされる…なんていう悲劇も(昔は)よくありました。
これを防ぐのが「ONユニット」という魔法の構文です。
ZERODIVIDE条件をキャッチする
PL/Iには「何かが起きたらこうしてね」という例外処理を定義する`ON`文があります。
1
/ ゼロ除算が発生した時の「避難経路」を定義します /
ON ZERODIVIDE
BEGIN;
PUT SKIP LIST(‘警告:ゼロ除算を検知しました。処理をスキップします。’);
/ ここでフラグを立てたり、ログを出して正常終了へ誘導したりします /
GOTO END_OF_PROCESS;
END;
/ 実際の計算処理 /
RESULT = VALUE / DIVISOR; / もしDIVISORが0なら、上のONユニットが発動! /
なぜこれが「安全」なのか?
`ON ZERODIVIDE` を定義すると、PL/Iの実行環境(ランタイム)が常に目を光らせてくれるようになります。ゼロ除算が起きた瞬間、プログラムの実行は一時停止し、自動的に `ON` ブロックの中へジャンプします。
これにより、「システム全体がクラッシュする」という最悪の事態を免れ、ログを残して安全に終了させるという、プロとしての立ち回りが可能になるわけです。
—
初学者が気をつけるべき「データ宣言」の罠
PL/Iを触る際、ぜひ覚えておいてほしいのが「データ属性」です。例えばこんな宣言。
1
DCL A FIXED DECIMAL(5, 0);
「FIXED DECIMAL」は、COBOLでいう `PIC S9(5)` です。メインフレーム特有の「パック10進数」を扱います。
PL/Iの面白いところは、演算のたびに精度(桁数)が自動で調整されることですが、それゆえにゼロ除算以外の例外も発生しやすいんです。
- FIXED DECIMAL: 厳密な数値計算用(金額など)
- FIXED BINARY: 高速な計算用(ループカウンタなど)
「計算が合わないな?」「なぜかオーバーフローするな?」と思ったら、この属性を見直すのが解決への近道です。
—
最後に:怖がらなくて大丈夫!
メインフレームのコードは一見難解に見えますが、それは「システムを止めないための備え」が厳重に組み込まれているからなんです。
今回紹介した `ON ZERODIVIDE` も、現場では「いかに異常を検知して、後続処理に影響を与えないか」という知恵の結晶です。もしバッチ改修でこのキーワードを見かけたら、「お、先人がシステムを守るための防波堤を築いてくれたんだな」と、温かい目で見てあげてくださいね。
皆さんのメインフレーム移行プロジェクトが、トラブルなくスムーズに進むことを心から応援しています。また何かあれば、いつでも聞きに来てくださいね!
