1. 導入:なぜON-UnitからのGOTO脱出が必要なのか
メインフレームのPL/I開発において、エラー処理は避けて通れない課題です。通常、ON-Unit(例外処理ルーチン)は処理を終えるとエラーが発生した直後の文へ戻る(RESUME)のが基本ですが、時には「エラーが発生したら処理を最初からやり直したい」「特定のクリーンアップ処理まで一気に戻りたい」というケースがあります。このような場合、スタックを強制的に巻き戻すための「GOTOによる脱出」が非常に強力な武器となります。これは複雑なエラー状態から安全に離脱するための、PL/Iらしい職人技とも言えるテクニックです。
2. 基礎知識:ON-Unitと制御の流れ
ON-Unitとは、特定の条件下(エラー発生時など)で自動的に実行されるコードブロックです。通常、ON-Unitが終了すると制御はエラーの発生源へ戻ります。しかし、プログラムの構造によっては、エラー発生箇所に留まることが致命的になる場合があります。ここで言う「GOTOによる脱出」とは、ON-Unit内部からプログラム内の任意のラベルへジャンプすることで、エラー発生時のスタックフレームを破棄し、意図した場所へ強制的に処理を移行させる手法を指します。
3. 実装と解決策
実装のポイントは「戻り先となるラベル」を明確に定義しておくことです。ON-Unit内からGOTOを使用することで、プログラムはエラー発生時の文脈を放棄し、指定したラベルから新しい処理を開始します。この手法は、入れ子になったループや複雑なサブルーチン呼び出しの中から一気に脱出する際に非常に有効です。
4. サンプルプログラム
以下は、エラー発生時にメインの処理ループへ強制的に戻る実装例です。
TEST_PGM: PROC OPTIONS(MAIN);
/ エラー発生時にメインループの先頭へジャンプするためのラベル /
MAIN_RETRY:
ON ERROR BEGIN;
/ エラー発生時のログ出力など /
PUT SKIP LIST('エラーを検知しました。処理を再試行します。');
/ ここでGOTOによりエラー発生箇所のスタックを破棄して脱出 /
GOTO MAIN_RETRY;
END;
/ メインの処理ループ /
DCL I FIXED BIN(15);
DO I = 1 TO 5;
IF I = 3 THEN
SIGNAL ERROR; / わざとエラーを発生させる /
PUT SKIP LIST('現在の処理回数: ' || I);
END;
END TEST_PGM;
5. 応用・注意点:移行と設計の視点
この手法を用いる際、最も注意すべきは「リソースの解放」です。GOTOで強制的に脱出すると、通常の終了処理(後処理)がスキップされる可能性があります。ファイルがオープンされたままになっていないか、メモリ領域が確保されたままになっていないかなど、脱出先のラベルに到達する前に必要なクリーンアップを行うよう設計してください。
また、現代的な言語(JavaやC#など)へ移行する際には、この「GOTO脱出」は例外(Exception)の投げ直しや、Retryパターンを用いた制御フローへと書き換える必要があります。PL/I特有のこの強力な制御フローを理解しておくことは、レガシー資産の仕様を読み解く上で非常に重要なスキルとなります。この手法は強力ですが、乱用するとコードの可読性を損なうため、あくまで「致命的なエラーからの復旧」など、限定的な用途で活用しましょう。

コメント