現場の視点:PL/Iの「予約語なし」という自由と、ON SUBSCRIPTRANGEという名の「守護神」
長年メインフレームの現場にいると、若手からよくこんな質問を受ける。「PL/Iって、なんでこんなに自由なんですか? 変数名に `IF` や `THEN` を使っても怒られないなんて、恐ろしくないですか?」と。
確かにそうだ。PL/Iは歴史的な経緯から厳密な予約語を持たない。だが、その自由さは諸刃の剣だ。今回は、そんなPL/Iの「奔放さ」を制御し、大規模バッチの安定稼働を守るための最も重要なツールの一つ、`ON SUBSCRIPTRANGE` について語ろうと思う。
—
1. 予約語なき世界の「罠」と「矜持」
PL/Iの設計思想において、識別子はコンテキストによって解釈される。例えば、`IF = 10;` と書いても、コンパイラは文脈からそれが代入文であると理解する。一見すると最強の言語だが、これに頼りすぎると可読性は地に落ちる。
保守現場では、「たとえ文法上許されても、言語機能の予約語を変数名には絶対に使わない」という暗黙の了解が、システムの神聖さを守る唯一の防波堤だ。この規律を守れないコードは、数年後の改修時に必ずエンジニアを苦しめることになる。
—
2. ON SUBSCRIPTRANGE:見えない境界線を可視化する
配列の添字範囲外アクセス(Subscript Range Error)は、メインフレームのバッチ処理において最も「発見が遅れる」バグの一つだ。運が悪ければ、隣接するメモリ領域を破壊し、数時間後の全く関係ない処理で異常終了(U0xxxなど)を引き起こす。
これを防ぐための `SUBSCRIPTRANGE` オプションだが、現場では以下のトレードオフを常に天秤にかける必要がある。
- デバッグ時(開発・単体テスト): 必ず有効化する。これがないと、致命的なバグが隠れたまま本番へ流出する。
- 本番稼働時: 実行時のオーバーヘッドを考慮し、無効化するか、あるいは「ONユニット」でトラップしてログを出力し、異常終了させる設計にする。
実践的な実装例
以下に、VSAMファイルから読み込んだデータを配列に格納し、境界チェックを組み込んだコードの雛形を示す。
1
/ ————————————————————- /
/ 配列境界チェックのデモンストレーション /
/ ————————————————————- /
TEST_PROG: PROC OPTIONS(MAIN);
DCL TABLE(10) CHAR(80); / 10要素の配列 /
DCL I FIXED BIN(15); / 添字用変数 /
/ 配列範囲外アクセスを検知するためのONユニット定義 /
ON SUBSCRIPTRANGE
BEGIN;
PUT SKIP LIST(‘!!! 致命的エラー: 配列の添字範囲外アクセスを検知 !!!’);
PUT SKIP LIST(‘ERROR LOCATION: ‘, ONLOC());
CALL ABEND_ROUTINE; / 異常終了処理へ /
END;
/ コンパイルオプションで SUBSCRIPTRANGE を有効にする必要がある /
/ 実際には、VSAM読み込み等のループ内で添字を制御する /
I = 11; / 明らかな範囲外エラー /
TABLE(I) = ‘DATA_ENTRY’; / ここでONユニットが発動する /
RETURN;
END TEST_PROG;
—
3. なぜ「実行時オーバーヘッド」を許容すべきか
「オーバーヘッドが怖いから本番ではオフにする」という意見は、小規模なプログラムなら理解できる。しかし、数百万件のレコードを扱う基幹バッチで、添字チェックを外すのはギャンブルと同じだ。
現代のIBM Zのハードウェア性能であれば、`SUBSCRIPTRANGE` のチェックコストは無視できるレベルに収束することが多い。むしろ、バグを見つけられず、データが破損した状態でサブシステム全体が汚染されるリスクのほうが、遥かに高くつく。
現場の知恵:デバッグのコツ
- コンパイル時の指定: プロダクションコードでも、パフォーマンス影響が極めてシビアな部分以外は、テスト環境と同様に `SUBSCRIPTRANGE` を指定しておくのがプロの現場の知見だ。
- BUILTIN関数の活用: `HBOUND(TABLE, 1)` や `LBOUND(TABLE, 1)` を徹底して使うこと。配列のサイズをマジックナンバーで書かず、常に境界値を動的に取得することで、修正に強いコードになる。
—
結びに:PL/Iを扱うということ
PL/Iは、書き手が「何をしているか」を厳密に意識しなければならない言語だ。予約語がないからこそ、変数名には意味を持たせ、境界チェックには誠実であるべきだ。
`ON SUBSCRIPTRANGE` を使いこなし、エラーを「予期せぬクラッシュ」ではなく「制御されたログ出力」に変えること。それが、大規模メインフレームシステムの安定稼働を支えるシステムアーキテクトとしての第一歩である。
次にコードをレビューする時、`DCL` の中身と `ON` ユニットの存在を確認してほしい。そこに、そのエンジニアの矜持が表れているはずだ。
