1. 導入:なぜCONTROLLED変数でUNDOが必要なのか
メインフレームの業務プログラムにおいて、処理の途中でエラーが発生した際、書き換えてしまった変数の値を元の状態に戻す(UNDOする)処理は非常に重要です。通常、バックアップ用の変数を用意して値を退避させる手法が一般的ですが、PL/Iの「CONTROLLED」記憶域クラスを活用すると、スタック構造を利用して、よりシンプルかつ安全に「1つ前の状態」を管理することができます。これは、複雑なリカバリロジックを簡潔に書くための強力なテクニックです。
2. 基礎知識:CONTROLLED記憶域クラスとは
通常、変数は宣言した時点でメモリが割り当てられますが、CONTROLLED記憶域クラスを使うと、プログラマが明示的に「ALLOCATE(メモリ確保)」と「FREE(メモリ解放)」を制御できます。
特筆すべきは、同じ名前の変数を複数回ALLOCATEすると、古いメモリがスタックの奥に押し込まれ、新しいメモリが前面に出てくる「世代管理」の仕組みです。これにより、最後にALLOCATEした値をFREEすれば、自動的に1つ前の値が再び参照可能になるという特性があります。
3. 実装/解決策:スタックによる状態の巻き戻し
処理の直前に現在の状態をALLOCATEすることで、値を「バックアップ」としてスタックに積みます。処理が正常に完了すれば、ALLOCATEした分をFREEします。もし処理中にエラーが発生した場合は、その段階でFREEを行うことで、即座に安全な「1つ前の状態」へ値を復元できます。
4. サンプルプログラム
以下のコードは、ステータス値を変更する際にUNDO機能を組み込んだ例です。
/ PL/I サンプル:CONTROLLEDを用いた簡易UNDO実装 /
TEST_UNDO: PROCEDURE OPTIONS(MAIN);
/ CONTROLLED属性で宣言 /
DCL STATUS CHAR(4) CONTROLLED;
/ 初期値を設定 /
ALLOCATE STATUS;
STATUS = ‘INIT’;
PUT SKIP LIST(‘現在の状態: ‘ || STATUS);
/ 変更前に現在の値をスタックに退避 /
ALLOCATE STATUS;
STATUS = ‘FAIL’; / 一時的に値を変更 /
PUT SKIP LIST(‘変更後の状態: ‘ || STATUS);
/ ここでエラーが発生したと仮定 /
PUT SKIP LIST(‘エラー発生!状態をロールバックします…’);
FREE STATUS; / 最新の値を破棄して、スタックから1つ前の値を復元 /
PUT SKIP LIST(‘復元後の状態: ‘ || STATUS);
FREE STATUS; / 最後に初期値を解放 /
END TEST_UNDO;
5. 応用・注意点:現場での運用におけるポイント
注意すべき点として、ALLOCATEとFREEの対を必ず意識することです。
もしALLOCATEを繰り返したままFREEを忘れると、メモリリークの原因となります。また、サブルーチン内でALLOCATEした変数は、そのスコープを抜けてもスタックから自動的には消えません。必ず「処理の出口」でFREEが実行されるよう、エラーハンドリング(ON ERRORなど)と組み合わせて設計するのが、メインフレーム開発における堅牢な実装のコツです。この仕組みを使いこなせば、複雑なフラグ管理も非常にスッキリと記述できるようになります。

コメント