こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他のモダンな言語や基幹言語の経験がある方にとって、IBMメインフレームの「PL/I(ピーエルワン)」という名前は、少し古めかしく、要塞のように堅牢で近寄りがたい雰囲気をまとって見えるかもしれませんね。
「なんだか変な記号がたくさん出てきそう…」
「予約語がないってどういうこと?」
そんな不安を抱えていらっしゃるかもしれませんが、どうぞ安心してください。一つひとつの仕様を紐解いていけば、PL/Iがいかに合理的で、プログラマの意図を汲み取ろうと設計された優しい言語であるかが分かってきます。
今回は、PL/Iの数ある特徴の中でも、画面や帳票への出力、あるいは他システムとの連携で必ずと言っていいほどぶ Burg(ぶつかる)壁――「PIC ‘9’ と ‘Z’ による編集文字の内部変換」について、じっくりと優しく解説していきますね。
—
1. 他言語からの挑戦者たちが驚く、PL/Iの「ピクチャ(PIC)句」の世界
Javaなら `DecimalFormat` や `String.format`、COBOLなら `PIC 9(5)V92` や `PIC ZZZ9` などを使って、数値を「見やすい形(カンマを入れたり、不要な先行ゼロを消したり)」に加工しますよね。
PL/Iでも、これはピクチャ(PICTURE または PIC)句を使って行います。しかし、PL/Iのピクチャ編集は、他言語のそれよりも一歩進んでいて、時々プログラマを「おや?」と驚かせる挙動をします。
まずは、よく使われる2つの文字の基本を押さえましょう。
- `9` (数値位置指定): その桁に数字が入ることを示します。足りない上位の桁には「ゼロ(0)」が補われます。
- `Z` (ゼロサプレッション): その桁の値が「ゼロ」のとき、スペース(空白)に置き換えてくれます(帳票の金額欄などで「000125円」ではなく「 125円」と綺麗に見せるアレです)。
言葉だけだと硬いので、身近な例えで考えてみましょう。
想像してみてください:電光掲示板の「型枠」
PL/Iの `PIC` 宣言は、数字をはめ込むための「専用の型枠」のようなものです。
例えば、ただの数字の「 125 」というデータを、`PIC ‘ZZZ9’` という型枠に流し込むと、掲示板の上で左側の不要なゼロがスッと消えて、`” 125″` という文字(文字型データ)に生まれ変わります。
—
2. 実行時に何が起きている?「内部変換」の裏側とコストの話
ここで、JavaやCOBOLの経験者ほど「おや?」と引っかかるポイントがあります。
それは、「この編集(見た目の加工)は、一体いつ行われているのか?」という点です。
PL/Iにおいて、`PIC ‘9’` や `PIC ‘Z’` を使った変数は、単なる数値(計算ができるバイナリやパック十進数)とはちょっと違います。これらは「文字(Character)データ」として扱われます。
つまり、次のような代入や演算が行われたとき、コンパイラやランタイムの裏側では何が起きているでしょうか?
1
DCL WK_NUM FIXED DECIMAL(5) INIT(125); / 純粋な計算用の数値型 /
DCL WK_EDIT PICTURE ‘ZZZ9’; / 編集用のピクチャ型(文字) /
WK_EDIT = WK_NUM; / ここで何が起きる? /
実行時のドラマ:暗黙の型変換(Implicit Conversion)
上記の代入文が実行された瞬間、PL/Iのランタイム(実行環境)は裏側でこっそりと次のような仕事をこなしています。
1. 数値から文字列への変換: 内部で持っている純粋な数値データ(パック十進数の `125`)を、一度「文字の ‘1’」「文字の ‘2’」「文字の ‘5’」というキャラクタ表現に変換します。
2. 編集パターンの適用: `ZZZ9` のルールに従い、上位の空いた桁をスペースで埋めます。結果として、メモリ上には `[ 】【 】【 1 】【 2 】【 5 】` という5バイトの文字データが完成します。
「便利さ」の裏にあるコストの意識
この自動変換(暗黙の変換)は、プログラマがわざわざ `TO_STRING` のような関数を書かなくて済むため非常にスマートです。しかし、基幹システムのアーキテクトとしての視点を持つなら、ここに「変換コスト(オーバーヘッド)」が存在することを忘れてはいけません。
もし、数百万件もある巨大なバッチ処理のループの中で、毎回このような数値とピクチャ編集項目の間で激しい型変換を行わせると、CPUのサイクルを無駄に消費し、バッチの実行時間が数分〜数十分も延びてしまう原因になります。
「編集は、画面や帳票、ファイルに出力する直前の最終ステップ(ラストワンマイル)だけで行う」
これが、メインフレームでパフォーマンスを出すための黄金律です。
—
3. 実務で役立つPL/Iコード例
百聞は一見にしかず。実際にどのようなコードを書くのか、実務を想定したサンプルを見てみましょう。日本語コメント付きですので、そのまま雰囲気を感じ取ってください。
1
/ ========================================================== /
/ ピクチャ編集文字の挙動を確認するサンプルプログラム /
/ ========================================================== /
EDT_DEMO: PROC OPTIONS(MAIN);
/ 変数の宣言 /
DCL W_AMOUNT FIXED DECIMAL(7,2) INIT(1234.56); / 計算用の数値(7桁、小数2桁) /
/ 編集用変数(文字型として扱われます) /
DCL OUT_ZEN_ZERO PICTURE ‘999999.99’; / ゼロ埋め表示用 /
DCL OUT_SUPPRESS PICTURE ‘ZZZ,ZZ9.99’; / ゼロサプレッション+カンマ編集 /
/ 1. ゼロ埋めパターン(PIC ‘9’)への代入 /
/ 入力値: 1234.56 -> 出力イメージ: 001234.56 /
OUT_ZEN_ZERO = W_AMOUNT;
PUT SKIP LIST (‘[0埋め編集] :’, OUT_ZEN_ZERO);
/ 2. ゼロサプレッションとカンマ編集(PIC ‘Z’ と ‘,’)への代入 /
/ 入力値: 1234.56 -> 出力イメージ: 1,234.56 (上位の不要なゼロがスペースになる) /
OUT_SUPPRESS = W_AMOUNT;
PUT SKIP LIST (‘[カンマ&Z編集]:’, OUT_SUPPRESS);
END EDT_DEMO;
コードの解説
- `FIXED DECIMAL(7,2)` は、COBOLでいう `PIC S9(5)V92 COMP-3` のようなものです。計算はこの型で行います。
- `OUT_SUPPRESS` に使われている `ZZZ,ZZ9.99` は、金額表示の王道です。もし値が `0.56` であったなら、` 0.56` のように綺麗に右寄せで出力されます。
—
4. 最後に:怖がらなくて大丈夫です
PL/Iのピクチャ編集は、一見すると記号の暗号のようで見慣れないうちは身構えてしまうかもしれません。しかし、それはデータに「こうありたい」という美しい衣装を着せてあげるための、言語からの親切なプレゼントです。
「数値の計算は計算用変数でしっかり行い、見せるときだけ `PIC ‘9’` や `PIC ‘Z’` のドレスを着せる」
この役割分担さえ頭の中に置いておけば、レガシーシステムの改修やモダン化の調査であっても、もう怖くありません。一つひとつ、ご自身のペースで紐解いていってくださいね。あなたのメインフレームの旅が実りあるものになるよう、陰ながら応援しています!
