PL/Iの「魔法」と「罠」:構造体をまるごと文字列として扱うSTRING関数の深淵
こんにちは。メインフレームの現場で何十年もコードと向き合ってきたシステムアーキテクトです。
JavaやCOBOLから来た皆さんがPL/I(ピーエル・ワン)のソースを初めて開いたとき、まず驚くのは「予約語がない」という独特の仕様ではないでしょうか。「`IF`という変数名が許されるなんて正気か?」と思うかもしれませんね。でも、ご安心ください。PL/Iは非常に柔軟で、実は非常に論理的な言語なんです。
今日は、そんなPL/Iの「自由さ」が生む強力な武器、`STRING`組み込み関数についてお話しします。構造体をまるごと一つの文字列として扱う……この一見乱暴で強力なテクニックを、メモリの仕組みと一緒に紐解いていきましょう。
—
1. 予約語がないという「自由」の正体
まず、PL/Iには「予約語」が存在しません。すべてが「文脈(コンテキスト)」で判断されます。
例えば、`IF = 1;` と書けば、コンパイラは「ああ、`IF`という名前の変数に1を代入するんだね」と理解します。もし `IF` がキーワードとして使われるなら、その場所は文法的に `IF` が来ると決まっている場所(条件式の先頭など)です。
この「自由」は、実は「コンパイラがめちゃくちゃ賢く(あるいは空気を読んで)文脈を判断している」という証拠なんです。この柔軟性があるからこそ、今回ご紹介する`STRING`関数の魔法も成立しています。
—
2. STRING関数:構造体を「文字列」に化かす魔法
データマイグレーションの現場で、構造体に入った顧客データや取引データを、そのまま外部ファイルへ書き出したり、通信電文として送信したりしたい場面はよくありますよね。
そんなとき、PL/Iの`STRING`関数を使うと、構造体の要素を一つずつ指定することなく、メモリ上の領域を「一つの巨大な文字列」として一気に扱うことができます。
実践コード例
/i
/ 顧客データを格納する構造体を定義 /
DCL 1 CUSTOMER_REC,
3 CUST_ID CHAR(5), / 顧客ID /
3 CUST_NAME CHAR(20), / 顧客名 /
3 CUST_AGE FIXED BIN(15); / 年齢 /
DCL WORK_STR CHAR(27) VARYING;
/ STRING関数を使って、構造体全体を文字列として扱う /
/ これにより、構造体の中身を一括で WORK_STR にコピーできます /
STRING(CUSTOMER_REC) = ‘A0001山田太郎 ‘ || ’25’;
/ 逆に、文字列から構造体へ一気に展開することも可能です /
WORK_STR = STRING(CUSTOMER_REC);
このコードのポイントは、「構造体という『箱』の形を無視して、中身のメモリをバイトの羅列として読み書きしている」という点です。
—
3. 避けては通れない「アライメント」の壁
さて、ここからが少しだけ上級者向けの「深淵」です。
PL/Iの構造体には、実は「アライメント(境界調整)」という概念があります。これは、CPUがメモリ上のデータに効率よくアクセスするために、データの開始位置を「4の倍数」などのキリの良い数字に揃える仕組みです。
もし、構造体の中に `FIXED BIN`(数値型)などが混ざっていると、コンパイラは勝手に「パディング(詰め物)」を入れます。
- 問題点: `STRING`関数で構造体を文字列として抜き出すと、この「見えないパディング」まで一緒に抜き出されてしまいます。
- 注意点: 別の言語(Javaなど)や異なるプラットフォームへこのデータを渡す際、このパディングの存在を知らないと、「なんだかデータがズレているぞ?」という不具合の原因になります。
解決策:UNALIGNED 属性を使う
もし、純粋なデータだけを詰め込みたい場合は、宣言時に `UNALIGNED` を指定しましょう。
/i
/ アライメントを無視し、メモリを詰めて配置させる宣言 /
DCL 1 CUSTOMER_REC UNALIGNED,
3 CUST_ID CHAR(5),
3 CUST_NAME CHAR(20),
3 CUST_AGE FIXED BIN(15);
これだけで、パディングが排除され、純粋なデータのみが連続して並びます。外部連携を行う際は、この `UNALIGNED` を使うのが業界の鉄則です。
—
最後に:怖がらなくて大丈夫です
PL/Iの構造体操作は、メモリという「生の領域」を直接触れるため、最初は少し怖く感じるかもしれません。しかし、一つずつ紐解いていけば、これほど強力で直感的な言語は他にありません。
「構造体はただの箱。`STRING`は、その箱を裏返して中身を全部ぶちまける魔法の関数」
そうイメージしてみてください。もし現場でデータがズレて困ったときは、まずは `UNALIGNED` 属性を確認する。これだけで、ベテランの仲間入りです。
また分からないことがあれば、いつでも聞きに来てくださいね。レガシーシステムの迷宮、一緒に攻略していきましょう!
