導入
メインフレーム開発において、意図しない値の書き換えは、デバッグ困難なバグの温床となります。特に共有領域やパラメータとして受け渡す定数的なデータに対し、誤って上書き処理を記述してしまう事故は少なくありません。今回解説する「NONASSIGNABLE」属性を活用すれば、コンパイル時に代入の不正を検知し、プログラムの堅牢性を劇的に向上させることが可能です。
基礎知識
PL/Iにおけるデータ宣言において、変数はデフォルトで「ASSIGNABLE(代入可能)」です。しかし、プログラムの実行中に値が変化してはならないデータに対しては、「NONASSIGNABLE」属性を付与します。これはJavaにおける「final」修飾子と同様の概念であり、一度初期化された値を読み取り専用として固定する仕組みです。CONSTANT属性と似ていますが、NONASSIGNABLEは初期値が静的である必要がないケース(プログラム実行時に計算された値を一度だけ設定し、以降は不変とする場合)にも柔軟に対応できる点が強みです。
実装/解決策
NONASSIGNABLE属性を使用する際は、宣言時にINIT句を用いて初期値を設定するのが一般的です。もし後続の処理で対象変数に対して代入(例:= 演算子やREAD文による値の上書き)を記述した場合、コンパイラは「エラー(または警告)」を出し、実行前にミスを指摘してくれます。これにより、不変であるべきデータが予期せぬ場所で書き換わるリスクを設計段階で排除できます。
サンプルプログラム
以下のサンプルコードは、設定値をNONASSIGNABLEとして定義し、誤った代入を防止する構造を示しています。
/ サンプルコード:NONASSIGNABLE属性の定義と利用例 /
PROCEDURE OPTIONS(MAIN);
/ 最大接続数などを定義。プログラム内で変更を許可しない /
DCL MAX_CONN FIXED BIN(15) NONASSIGNABLE INIT(100);
/ 現在の接続数 /
DCL CURR_CONN FIXED BIN(15) INITIAL(0);
/ 正常な処理:読み取りは可能 /
IF CURR_CONN < MAX_CONN THEN DO;
CURR_CONN = CURR_CONN + 1;
END;
/ 誤った処理:NONASSIGNABLE変数への代入を試みる /
/ この行はコンパイル時にエラーとなり、重大なミスを防ぐ /
/ MAX_CONN = 200; /
END;
応用・注意点
現場での移行プロジェクトや新規設計において、この属性を意識的に活用するポイントは「Value Object(値オブジェクト)」としての設計思想です。特に共通モジュールで参照されるパラメータや、ビジネスロジック上の定数を定義する際、機械的にNONASSIGNABLEを付与するコーディング規約を策定することをお勧めします。
注意点として、NONASSIGNABLEを指定した変数は、初期化時以外に値を更新できないため、誤ってループカウンタや計算途中結果の保持変数に使用しないよう注意してください。また、古いコンパイラ設定によっては警告レベルが低く設定されている場合があるため、チーム全体でコンパイルオプション(メッセージの重要度設定)を最適化しておくことが、この機能の効果を最大化する鍵となります。

コメント