【入門編】INITIAL属性による変数の初期化 – PL/Iの基本構文とデータ制御実践ガイド

【PL/I入門】「INITIAL属性」の挙動を理解する:JavaやCOBOL経験者が陥りやすい落とし穴

こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLでバリバリ開発してきたあなたにとって、PL/I(ピーエル・ワン)のソースコードを初めて見たとき、「あれ、これ予約語はどこにあるの?」とか「変数の初期化ってどうなってるの?」と戸惑うことはありませんか?

PL/Iは、1960年代に生まれた非常に多機能で、かつ「プログラマの意図を汲み取ろうと頑張りすぎる」言語です。今日は、その中でも特に実務でバグの温床になりがちな「INITIAL属性による初期化」について、現場の知見を交えて紐解いていきましょう。

1. そもそもPL/Iには「予約語」がない?

まず、JavaやCOBOLに慣れた人が一番驚くのが「予約語の概念」です。
PL/Iには、厳密な意味での「予約語」が存在しません。つまり、`IF`や`THEN`といったコマンドですら、変数名として使えてしまうのです。

/i
/ 極端な例:IFという名前の変数を宣言できてしまう /
DCL IF FIXED BIN(15);
IF = 10;

一見、「なんて自由なんだ!」と思いますが、これは諸刃の剣です。読みやすいコードを書くためには、ルールを自分たちで決める必要があります。この「自由度」こそが、PL/Iがレガシーの現場で愛されつつも、時に恐れられる理由なんですね。

2. INITIAL属性:変数の「最初の姿」を定義する

PL/Iでの変数宣言には`DCL`(DECLARE)を使います。その際、値をあらかじめセットしておきたいときに使うのが`INITIAL`属性です。

基本的な書き方

/i
DCL COUNTER FIXED BIN(31) INITIAL(0);
DCL STATUS CHAR(10) INITIAL(‘READY’);

これは分かりやすいですね。Javaで言えば `int counter = 0;` に相当します。しかし、ここで一つ重要な注意点があります。「これはいつ実行されるのか?」という点です。

3. 「宣言時」と「プロシージャ呼び出し時」の再初期化の罠

ここが今回のメインテーマです。Javaのクラスフィールド初期化と、PL/Iのプロシージャ内での初期化には、大きな違いがあります。

サンプルコードで比較してみましょう

/i
DEMO_PROC: PROCEDURE;

/ 内部プロシージャ /
CALC_SUB: PROCEDURE;
DCL WORK_VAR FIXED BIN(15) INITIAL(0);

WORK_VAR = WORK_VAR + 1;
PUT SKIP LIST(‘現在の値は:’, WORK_VAR);
END CALC_SUB;

/ 3回呼び出してみる /
CALL CALC_SUB; / 1回目 /
CALL CALC_SUB; / 2回目 /
CALL CALC_SUB; / 3回目 /

END DEMO_PROC;

この挙動はどうなると思いますか?

「あ、毎回初期化されるから、全部『1』が出力されるよね?」と思いましたか?
実は、その通りです。

PL/Iのプロシージャ内で宣言された変数は、そのプロシージャが呼び出されるたびにスタックメモリ上に生成され、`INITIAL`属性によって値がリセットされます。

注意すべき「STATIC」属性との組み合わせ

もし、この変数に`STATIC`という属性がついたらどうなるでしょう。

/i
DCL WORK_VAR FIXED BIN(15) STATIC INITIAL(0);

`STATIC`をつけると、この変数は「プログラムの実行中、ずっと同じメモリ領域を使い回す」ことになります。この場合、2回目以降の呼び出しでも値が保持されるため、出力は「1, 2, 3」と増えていくことになります。

現場の教訓:
バッチ処理のマイグレーション時、前回のループの値を保持し続けたいのに`STATIC`を忘れて「なぜか値が初期値に戻る!」というトラブルは、初心者が通る道です。逆に、値をリセットしたいのに`STATIC`が残っていて「ゴミデータが残っている!」と悩むケースも非常に多いのです。

4. 初学者へのアドバイス:怖がらずに「スコープ」を意識しよう

PL/Iの変数は、その変数が「どこで生きているか(スコープ)」と「いつまで生きているか(ストレージ属性)」が明確に分かれています。

  • AUTO(デフォルト): プロシージャに入るたびに初期化される。一時的な計算用ならこれ。
  • STATIC: プログラム終了まで値を保持し続ける。累積計算や、設定値の保持ならこれ。

最初は「`INITIAL`は、その変数が生まれた瞬間にだけ一度だけ働く魔法の命令」と覚えておけば大丈夫です。

まとめ

1. 予約語がないからこそ、変数名には意味のある名前を付けよう。
2. `INITIAL`属性は、変数の「誕生時」に働く。
3. `STATIC`が付くと、その変数は死ぬまで(プログラム終了まで)値を忘れない。

PL/Iは歴史が長い分、書き方も多様です。でも、一つひとつ紐解けば、メインフレームの堅牢な世界を支える非常に論理的な言語であることが分かるはずです。

もし「この変数の挙動がどうしても怪しい…」というときは、まずは`STATIC`が付いていないか、そしてその変数がどのスコープで宣言されているかを確認してみてくださいね。

それでは、次回のメインフレーム・アーキテクチャでお会いしましょう!

タイトルとURLをコピーしました