「INITIAL属性」の罠を突破せよ!PL/Iの変数初期化とPROCEDUREの深淵
メインフレームの世界へようこそ。COBOLやJavaを使い慣れた方にとって、PL/Iのコードを初めて目にした時の「なんだこの独特な記法は……」という戸惑いは、誰もが通る道です。
今日は、PL/Iの初学者が必ず一度は躓く「INITIAL属性による変数の初期化」というテーマを紐解いていきましょう。ここを理解しておかないと、バッチ処理で「なぜか変数が前回の値のまま残っている!」という、夜中に冷や汗をかくようなバグに遭遇することになります。
—
1. PL/Iの基本の「キ」:PROCEDUREとPACKAGE
まず、PL/Iのプログラムは `PROCEDURE` という単位で動きます。Javaでいうクラスやメソッドに近い存在ですが、PL/Iはもっと自由奔放です。
1
/ プログラムの入り口は OPTIONS(MAIN) で指定します /
SAMPLE_PROG: PROCEDURE OPTIONS(MAIN);
/ ここにロジックを書きます /
END SAMPLE_PROG;
`OPTIONS(MAIN)` がついた手続きがプログラムの開始地点です。この中で変数を宣言し、値を操作していくわけですね。
—
2. INITIAL属性:変数の「最初の姿」
変数を宣言する際、`INITIAL`(初期値)を指定することができます。これはJavaの `int count = 0;` と同じ感覚で使えます。
1
DCL COUNTER FIXED BIN(31) INITIAL(0); / カウンタを0で初期化 /
しかし、ここからがPL/Iの面白い(そして注意が必要な)ところです。「この初期化は、一体いつ行われるのか?」 という問題です。
結論:INITIALは「PROCEDUREが呼ばれるたびに」発動する
PL/Iの `INITIAL` 属性は、そのPROCEDUREが呼び出される(エントリされる)たびに再評価され、設定されます。
「なんだ、当たり前じゃないか」と思いましたか?
実は、ここがCOBOLの `VALUE` 句とは少し違う点です。COBOLではデータ領域が静的に確保されるイメージですが、PL/Iは `AUTOMATIC`(自動記憶クラス)という属性がデフォルトで適用されているため、PROCEDUREを抜けると変数のメモリ領域は解放され、次に呼ばれるときはまた真っ新な状態から始まるのです。
—
3. 現場で泣かないための「落とし穴」
もし、あなたが「この変数はPROCEDUREをまたいでも値を保持してほしい(静的変数が欲しい)」と考えたとき、安易に `INITIAL` を使うと痛い目を見ます。
逆に、値を保持したい場合は `STATIC` 属性を組み合わせる必要があります。コードで比較してみましょう。
1
TEST_PROC: PROCEDURE;
/ 1. 自動変数:呼ばれるたびに毎回0に戻る /
DCL AUTO_VAR FIXED BIN(31) INITIAL(0);
/ 2. 静的変数:初回のみ0になり、以降は値を保持し続ける /
DCL STATIC_VAR FIXED BIN(31) STATIC INITIAL(0);
AUTO_VAR = AUTO_VAR + 1;
STATIC_VAR = STATIC_VAR + 1;
PUT SKIP LIST(‘AUTO:’, AUTO_VAR, ‘STATIC:’, STATIC_VAR);
END TEST_PROC;
- AUTO_VARの場合: 毎回 `0` からスタートするので、何回呼んでも出力は `1` です。
- STATIC_VARの場合: 呼び出すたびに `1, 2, 3…` と増えていきます。
「初期化したいだけなのに、なぜか前回のゴミが残っている」というトラブルの多くは、この `STATIC` 属性をうっかり付けてしまっているか、あるいは逆に `STATIC` が必要なのに省略してしまっているケースがほとんどです。
—
4. スペシャリストからのアドバイス
初学者の皆さんに一つだけ覚えておいてほしいことがあります。
PL/Iはコンパイラが非常に賢い言語です。`INITIAL` を付けると、コンパイラはその変数のために「初期化用のコード」を内部でせっせと生成します。もし巨大な配列を `INITIAL` で初期化すると、プログラムが起動するたびにその初期化処理が走り、パフォーマンスに影響することもあります。
「初期化が必要な時だけ、適切な記憶クラス(AUTOMATICかSTATICか)を選んで使う」
これが、レガシーシステムを軽快に動かすための第一歩です。PL/Iは古い言語ですが、メモリの扱いが非常に明快で、理にかなった設計をしています。
「なんだか難しそう」と身構えず、まずは簡単なPROCEDUREを書いて、`DISPLAY`(または `PUT LIST`)で変数の値を追いかけてみてください。一つずつ紐解けば、PL/Iはあなたの頼もしい武器になってくれますよ!
次回は、この変数をより複雑にする「構造体(STRUCTURE)」と、そのメモリ配置の妙についてお話ししましょう。それでは、良きメインフレーム・ライフを!
