PL/Iの「VARYING」って何者?文字列の裏側を覗いてみよう
こんにちは!IBMメインフレームの世界へようこそ。
JavaやCOBOLといったモダン、あるいは堅実な言語を使いこなしてきた皆さんにとって、PL/Iは少し「古風で近寄りがたい」存在に見えるかもしれませんね。でも安心してください。PL/Iは、極めて論理的で、コンピュータのメモリ構造を正直に反映した、非常に「正直な」言語なんです。
今回は、PL/Iで頻繁に出くわす`CHARACTER(n) VARYING`というデータ型について、その「中身」を紐解いていきましょう。
—
そもそも「VARYING」って何?
Javaの`String`やCOBOLの`PIC X(n)`に慣れていると、PL/Iの文字列宣言には少し戸惑うかもしれません。
- `CHARACTER(10)`: 固定長文字列。箱のサイズが10と決まっていて、短い値を入れても残りは空白で埋められます(COBOLの固定長に近いですね)。
- `CHARACTER(10) VARYING`: 可変長文字列。箱のサイズは最大10ですが、中身に合わせて「伸縮」します。
ここで初学者がつまずくポイントは、「メモリ上ではどうなっているの?」という点です。実は、このVARYING型、先頭の2バイトに「現在何文字入っているか」という長さ情報が隠されているのです。
—
内部構造をイメージで理解しよう
皆さんが持っている「ノート」を想像してください。
- 固定長は、あらかじめ10行の罫線が引いてあるノート。文字が少なくても、残りの行は空白のままです。
- VARYINGは、ノートの最初のページに「今、何行目まで書いたよ」と書く欄があるノートです。
PL/Iのメモリ上では、以下のように配置されています。
| 1-2バイト目 | 3バイト目〜 |
| :— | :— |
| 長さ情報 (バイナリ) | 実際の文字列データ |
この「先頭の2バイト」が曲者です。プログラムがこの変数を使うたびに、PL/Iは「おっと、まずは先頭2バイトを読んで、どれだけデータを読み込めばいいか確認しなきゃ」と働きます。これが、後のパフォーマンスの話に繋がってきます。
—
実践!PL/Iコードで確認してみよう
実際にプログラムでどう書くのか、簡単な例を見てみましょう。
/i
/ メインプログラムの定義 /
TEST_PROG: PROCEDURE OPTIONS(MAIN);
/ 最大32767文字まで入る可変長文字列を宣言 /
DCL MY_NAME CHAR(20) VARYING;
/ データを代入してみる /
MY_NAME = ‘IBM_MAINFRAME’;
/
この時、メモリの中身はこうなっているはずです:
先頭2バイト: 13 (文字列 ‘IBM_MAINFRAME’ の長さ)
3バイト以降: ‘IBM_MAINFRAME’ + 残りの領域
/
PUT SKIP LIST(‘現在の長さは: ‘ || LENGTH(MY_NAME));
END TEST_PROG;
—
パフォーマンスと「お作法」の話
「毎回長さをチェックするなら、固定長より遅いのでは?」
鋭いご指摘です。その通り、CPUの観点で見れば、固定長の方がわずかに高速です。
しかし、基幹システムでは「データの転送量」がボトルネックになることが多々あります。例えば、数千文字のフィールドで、実際に埋まっているのが数文字しかない場合、VARYINGを使えば「長さ情報+実データ」だけで通信できるため、ネットワーク負荷やストレージ効率が劇的に改善します。
注意すべき「奇妙な」仕様
- 最大長: `VARYING`は最大で32,767バイトです。これを超える場合は`VARYINGZ`(NULL終端)や`WIDECHAR`などを検討しますが、基本はこの32KBの壁を意識してください。
- 文字列結合のコスト: 頻繁に`||`(連結演算子)で文字列を繋ぐ処理をループ内で行うと、そのたびに「長さ情報の更新」と「メモリの再割り当て」が発生します。もし大量の連結を行うなら、StringBuilderのように一度で構築する工夫が必要です。
—
最後に:怖がらなくて大丈夫!
PL/Iの`VARYING`は、コンピュータが効率よくデータを扱うために用意された、先人の知恵が詰まった構造です。「先頭に長さ情報がいる」と知っているだけで、デバッグの際にも「あ、この値がおかしいのは長さ情報の計算がどこかで狂っているのかも?」と、メモリダンプを読み解く力が格段に上がります。
メインフレームのコードは、時に難解に見えるかもしれません。でも、一つずつ紐解いていけば、そこには必ず論理的な理由があります。またいつでも、この「メインフレーム道場」に質問しに来てくださいね!
それでは、良いコーディングライフを!
