メインフレームの守護神:PL/Iで「ゼロ除算」を華麗に受け流す方法
こんにちは!メインフレームの世界へようこそ。
COBOLやJavaを経験してきた方にとって、PL/Iは少し「独特なクセ」を持つ言語に見えるかもしれません。しかし、一度その哲学を理解すれば、これほどまでに堅牢で、プログラマの意図を汲み取ってくれる言語は他にありません。
今回は、基幹システムの現場で避けては通れない「ゼロ除算(ZERODIVIDE)」という悪魔のようなエラーを、PL/Iの強力な武器である「ONユニット」を使って、スマートに飼い慣らす方法を伝授します。
—
そもそも、PL/Iの「ONユニット」って何?
他の言語でゼロ除算が発生すると、例外が投げられてプログラムが強制終了(異常終了)するのが一般的ですよね。でも、PL/Iの世界には「ONユニット」という、いわば「トラブルが発生した瞬間に発動する自動防衛システム」が備わっています。
「計算がゼロで割られそうになったら、黙ってプログラムを落とすのではなく、この処理を挟んでくれ!」とあらかじめ予約しておく仕組みです。これができるだけで、夜中のバッチジョブが予期せぬゼロ除算でストップする悪夢から解放されます。
—
実践!ゼロ除算をトラップするコード例
まずは、実際のコードを見てみましょう。PL/Iは伝統的に大文字で記述するのがお作法です。
1
TEST_CALC: PROCEDURE OPTIONS(MAIN);
/ 変数の宣言:FIXED BIN(15)はCOBOLでいうCOMP相当の整数型です /
DCL DIVIDEND FIXED BIN(15) INIT(100);
DCL DIVISOR FIXED BIN(15) INIT(0); / ここがゼロなのでゼロ除算が起きます /
DCL RESULT FIXED BIN(15);
/ ONユニットの定義:ZERODIVIDEが起きたらこの処理を呼べ、という命令 /
ON ZERODIVIDE
BEGIN;
PUT SKIP LIST(‘警告: ゼロ除算を検知しました。代替値をセットします。’);
RESULT = 0; / 異常終了させる代わりに、値を0に補正して継続させる /
GOTO CALC_CONTINUE; / 処理の続きへジャンプ /
END;
/ 計算処理 /
RESULT = DIVIDEND / DIVISOR;
CALC_CONTINUE:
PUT SKIP LIST(‘計算結果は: ‘ || RESULT);
END TEST_CALC;
このコードのポイントを紐解く
1. ON ZERODIVIDE: これが「監視の目」です。プログラムが実行されている間、システムはこのコードが通るたびに「ゼロ除算が起きていないか?」を常に監視しています。
2. BEGIN; ~ END;: 監視対象のイベントが起きた際に、実行する処理のブロックです。ここで「値を0にする」というリカバリーを行うのがコツです。
3. GOTOでの復帰: 非常にレガシーな手法に見えるかもしれませんが、PL/IのONユニット制御では、処理を正常なルートに戻すための伝統的な手法です。
—
なぜ「異常終了」させないのか?
「エラーなら止めてログを出したほうが安全では?」と思われるかもしれません。しかし、基幹システムのバッチ処理においては、「たった一つのレコードの計算エラーで、1時間かかる全件処理を止めてしまう」ことの方が、ビジネス上の損失が大きいケースが多々あります。
「ゼロで割ってしまうようなデータは、ひとまず0として処理を完遂させ、後でログを追跡する」といった柔軟な運用ができる点こそ、PL/Iが長年メインフレームの現場で愛され続けている理由なのです。
—
初学者が気をつけるべき「罠」
最後に、PL/Iを触り始めたばかりの方がハマりやすいポイントを一つ。
- スコープ(有効範囲): ONユニットは、定義されたPROCEDURE(またはBEGINブロック)の中でのみ有効です。処理が関数をまたぐ場合、どこでONユニットを定義するかは非常に重要です。
- 属性の宣言: 今回は `FIXED BIN` を使いましたが、`DECIMAL FIXED` など、PL/Iには独自の数値属性が豊富にあります。宣言した型によって、ゼロ除算の判定基準や動作が微妙に異なることもあるため、仕様書はぜひ「辞書」として手元に置いておいてくださいね。
—
最後に:怖がらなくて大丈夫です
PL/Iは、一見すると無機質で古い言語のように感じるかもしれません。しかし、その中身は非常に親切で、プログラマが「こう動いてほしい」と願うことを、極めて高い自由度で実現させてくれます。
ゼロ除算が起きたからといって、プログラムを闇雲に落とす必要はありません。ONユニットという「賢い盾」を使いこなして、安定したシステム運用を目指しましょう!
もし、特定のデータ型での挙動や、マイグレーション時のハマりどころなどがあれば、いつでも聞いてくださいね。一緒に紐解いていきましょう!
