PL/Iの迷宮を歩く:BEGINブロックとPROCEDUREブロック、その「見えない壁」の正体
こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLの経験がある方にとって、PL/Iは「古臭くて難解な言語」に見えるかもしれません。確かに、IBMメインフレームの歴史とともに歩んできたこの言語には、独特の癖があります。
今日はその中でも、特に初学者が「あれ?なぜ変数の値が変わらないの?」と頭を抱えがちな、「BEGINブロックとPROCEDUREブロックのスコープ(有効範囲)の差異」について、現場の知見を交えて紐解いていきましょう。大丈夫、一つずつ整理すれば恐れることはありません。
—
1. まずは「箱」の概念を整理しましょう
PL/Iにおいて、プログラムの単位は基本的に`PROCEDURE`です。COBOLでいう「プログラム(またはセクション)」、Javaでいう「クラスやメソッド」に近いですね。
一方で`BEGIN`ブロックは、今のコードの途中に「囲い(スコープ)」を強引に作るためのものです。
- PROCEDURE: 新しい「仕事の場」です。変数の持ち主(親)が変わるようなイメージですね。
- BEGIN: 今いる場所の「小部屋」です。変数は親のものをそのまま使えますが、自分専用の小さなクローゼット(ローカル変数)も作れます。
—
2. スコープの決定的な違い
Javaなどで慣れていると、「{}」で囲めばどこでもスコープができると思いがちですが、PL/Iの`PROCEDURE`には「動的スコープ」という面白い(そして時に恐ろしい)性質があります。
BEGINとPROCEDUREの決定的な差:ONユニットの挙動
ここが一番の落とし穴です。エラーが発生した時に走る「ONユニット(例外処理)」を定義したとき、その影響範囲がどこまで及ぶかという話です。
- BEGINブロック: そのブロック内で定義されたONユニットは、そのブロックが終了した瞬間に消滅します。
- PROCEDUREブロック: 手続き(プロシージャ)を呼び出すと、呼び出した側の環境に影響を及ぼしたり、逆に呼び出し先の環境から影響を受けたりします。
百聞は一見に如かず。コードで見てみましょう。
1
/ PL/Iのプログラム例:スコープの挙動を確認する /
DEMO_PROC: PROC OPTIONS(MAIN);
DCL MSG CHAR(20) INIT(‘グローバル’);
/ BEGINブロックの開始 /
BEGIN;
DCL MSG CHAR(20) INIT(‘ローカル’);
PUT SKIP LIST(‘BEGINの中のMSG: ‘ || MSG);
/ ここではローカルの’ローカル’が表示されます /
END;
PUT SKIP LIST(‘BEGINの外のMSG: ‘ || MSG);
/ ここでは外側の’グローバル’に戻ります /
/ 次にONユニットの実験 /
ON CONVERSION BEGIN;
PUT SKIP LIST(‘エラーをキャッチしました!’);
END;
/ このPROCの中で発生した変換エラーは、上記のONユニットが拾います /
/ しかし、別のPROCを呼び出した場合、そちらのONユニットが優先されることもあります /
END DEMO_PROC;
—
3. なぜ「動的スコープ」が現場で重要なのか
PL/Iの「動的スコープ」とは、「どのソースコードの場所で定義されたか」ではなく、「どの実行順序で呼び出されたか」によって有効な変数やONユニットが決まるという性質を指します。
例えば、基幹システムのバッチ処理で、途中で別のサブプログラムをCALLしたとします。そのサブプログラム内で `ON ERROR` が定義されると、メインのプログラムまでその影響が「逆流」してくることがあるのです。
「なぜか予期せぬエラーハンドラが動いている!」というトラブルの多くは、この動的スコープによって、呼び出し先のONユニットが呼び出し元の処理を上書きしてしまっていることが原因です。
初心者の方へのアドバイス
1. BEGINブロックを多用しない: 複雑な制御が必要な時以外は、極力PROCEDUREを単位として整理しましょう。
2. ONユニットの範囲を意識する: `REVERT`ステートメントを使って、ONユニットを必要な場所で確実に解除する癖をつけると、トラブルは激減します。
3. 変数の名前を使い回さない: メモリが貴重だった時代の名残で変数名を短くしがちですが、スコープをまたぐ場合は意図的に長い名前にして衝突を防ぐのが、現代のメインフレーム開発の定石です。
—
最後に:怖がる必要はありません
PL/Iは、非常に論理的で、一度マスターすれば「なぜ昔のシステムがこれほどまでに堅牢だったのか」が手に取るようにわかる言語です。
`BEGIN`ブロックは、あなたのプログラムに「一時的な隠れ家」を作ってくれる便利な道具です。その特性さえ理解してしまえば、メモリの管理や例外処理を自在にコントロールできる強力な武器になります。
もし現場で「変数が書き換わらない!」「ONユニットが意図せず動く!」と悩んだら、それはあなたがPL/Iのスコープという「深い森」に足を踏み入れた証拠です。いつでもここに立ち返って、変数の「住処」を確認してみてください。
それでは、次回のメインフレーム・アーキテクチャ講座でお会いしましょう。ハッピー・コーディング!
