こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他のプログラミング言語の経験がおありの方にとって、IBMメインフレームの基幹システムで現役バリバリ動いている「PL/I(ピーエルアイ)」という言語は、ちょっと古風で、どこか近寄りがたい雰囲気に感じられるかもしれませんよね。
「なんだか変数名のルールも独特だし、記号だらけで難しそう……」
そんな風に身構えてしまう方も多いのですが、大丈夫です!一つずつフタを開けて中身を見ていけば、PL/Iは非常に合理的で、私たちの意図をしっかりと汲み取ってくれる優しい言語なんです。
さて、今回はPL/Iの数ある特徴の中でも、帳票出力や画面表示のバッチ処理で毎日のように顔を合わせる「数値編集(PICTURE句)」、特に先行ゼロを消してくれる「Z」と、常に数字を守り抜く「9」の決定的な違いについて、実務の現場のノウハウを交えながらたっぷりとお話ししていきますね。
—
そもそもPL/Iの数値編集ってなに?
Javaなどで数字を画面やファイルに出力するとき、`DecimalFormat`や`String.format`を使って「0埋めしたい」「不要な頭のゼロを消したい」といった整形をしたことがありませんか?
PL/Iでは、これに相当する処理をデータ宣言の段階、つまり変数定義の `PICTURE(または PIC)` 句で指定します。例えば、純粋な計算用の数値(演算項目のデータ)を、人間が見やすい「文字」の形にパッと変えてあげる魔法のような機能です。
ここで初心者の壁になりやすいのが、「9」と「Z」という、たった一文字のピクチャ編集文字の挙動の差なんです。
—
1. 固定の守り神「PIC ‘9’」の挙動と性格
まずは、お馴染みの「9」から見ていきましょう。
COBOLを触ったことがある方なら「あ、いつもの奴ね」とピンとくるはずですが、Javaしか知らない方にとっては少し新鮮かもしれません。`PIC ‘9’` は、「指定した桁数の数字を必ずそこに表示しなさいよ」という厳格な番人です。
実際にコードで見てみましょう
1
/ ========================================================== /
/ PIC ‘9’ と PIC ‘Z’ の挙動を比較するサンプルプログラム /
/ ========================================================== /
TEST_SAMPLE: PROC OPTIONS(MAIN);
/ 内部計算用のフルサイズ数値(5桁の整数) /
DCL W_KETA_NUM PIC ‘99999’ INIT(123);
/ 編集後の出力用変数(PIC ‘9’ と PIC ‘Z’) /
DCL OUT_PAT_9 PIC ‘99999’;
DCL OUT_PAT_Z PIC ‘ZZZZ9’;
/ データを代入して編集する /
OUT_PAT_9 = W_KETA_NUM;
OUT_PAT_Z = W_KETA_NUM;
/ 結果を表示(SYSOUTへ出力) /
PUT SKIP EDIT (‘PIC 9 の結果:’, OUT_PAT_9) (A(13), A(5));
PUT SKIP EDIT (‘PIC Z の結果:’, OUT_PAT_Z) (A(13), A(5));
END TEST_SAMPLE;
このプログラムを実行したとき、変数 `OUT_PAT_9` には何が入ると思いますか?
中身は `123` という小さな数字ですが、変数の定義は `PIC ‘99999’`(5桁)です。
答えはこうなります:
`00123`
そう、足りない上位の桁には、容赦なく「0(ゼロ)」がパディング(埋め込み)されます。これが「固定的な数字表示」である `9` の挙動です。帳票などで「口座番号やコード値を必ず固定桁数でビシッと揃えて出力したい!」という場合には、この `9` が最高の相棒になります。
—
2. 先行ゼロの隠し芸「PIC ‘Z’」の挙動と優しさ
では次に、今回の主役の一つである `PIC ‘Z’` です。
先ほどのコードで `OUT_PAT_Z` には `PIC ‘ZZZZ9’` を指定していました。さて、同じ `123` を代入したとき、こちらはどう出力されるでしょうか?
答えはこうなります:
` 123` (※手前に半角スペースが2つ入ります)
おや? ゼロが消えて、代わりにスペースになりましたね!
これが、`Z`(Zero-suppress:ゼロサプレッション)の最大の特長です。
Zの仕組みをイメージしてみよう
`Z` は、「もしその桁の中身がゼロだったら、恥ずかしいから隠して(スペースに置き換えて)あげるね。でも、有効な数字が出てきたら、そこからはちゃんと表示するよ!」という、なんとも気配りのできた優しい文字編集です。
実務の現場で金額や数量を扱うときを想像してみてください。
例えば、最大9桁入る売上金額の定義を `PIC ‘999999999’` にしていたとします。そこに今日の売上が「5,000円」だったからと代入すると、画面や帳票にはこう表示されてしまいます。
`000005000`
なんだか見づらいですよね。「00000」なんて並んでいたら、パッと見でいくらなのか脳内で桁合わせをするのにワンテンポ遅れてしまいます。
ここで `PIC ‘ZZZZZZ999’` や `PIC ‘ZZZ,ZZZ,ZZ9’` のように `Z` を配置してあげると、余計な先行ゼロが綺麗に消え去り、` 5000` のように右詰めでスッキリと読みやすい形で出力されるというわけです。
—
3. ここで注意!実務でハマりがちな「Zの罠」
「なるほど、じゃあ全部 `Z` にしちゃえば見やすくて万能じゃん!」
そう思ったそこのあなた、ちょっと待ってください!ここにレガシーシステムならではの、思わず冷や汗をかくポイントがあるんです。
① すべてを `Z` にしてはいけない理由
もし、すべての桁を `Z` にした変数 `DCL MONEY_ALL PIC ‘ZZZZZ’;` を用意し、そこに完全な「0(ゼロ)」を代入したとします。
その結果、何が出力されると思いますか?
なんと、完全な「空白(スペース5つ)」になって出力されてしまうんです!
「0円」という事実を表現したいのに、すべてがスペースになってしまうと、帳票が真っ白になってしまい「データが抜けている(未設定なのか?)」のか「0円なのか」がシステム側から人間には判別がつかなくなってしまいます。
そのため、実務の現場では、一番下の桁(最下位桁)には必ず `9` を残しておくのが鉄則です。
- NG例: `PIC ‘ZZZZZ’` (0のときに完全な空白になる)
- OK例: `PIC ‘ZZZZ9’` (0のときでも最低限 `0` が1文字だけ表示される)
この「末尾の一桁だけは `9` にしておく」というテクニックは、基幹システムの帳票設計において先輩たちが代々受け継いできた、いわば知恵の結晶なんです。
—
4. PL/Iならではの「予約語がない」自由さと落とし穴
さて、ここまで `PIC` や `DCL` といった構文を見てきましたが、PL/Iの非常にユニークな特徴として「PL/Iには厳密な意味での『予約語(Keyword)』が存在しない」という仕様があります。
どういうことかと言うと、Javaの `public` や `class`、COBOLの `MOVE` や `PICTURE` のように、「この単語は絶対に変数名として使ってはいけない!」という決まりがPL/Iにはありません。
例えば、極端な話ですが、こんなコードもPL/Iのコンパイラは怒りません。
1
/ ちょっとお茶目な(だけど絶対にやっちゃいけない)変数宣言 /
DCL PICTURE PIC ‘999’;
DCL DCL PIC ‘999’;
DCL PROC PIC ‘999’;
「えっ、変数名に `PICTURE` や `DCL` を使えちゃうの!?」
そうなんです。コンパイラは前後の文脈(コンテキスト)から、「おっ、ここは宣言文の中だな」「ここは変数名だな」と賢く判断してくれるため、キーワードと同じ文字列を識別子(変数名)として使えてしまうのです。
しかし、現場のプログラマとしての作法は別!
言語仕様上は可能だからといって、変数名に `PICTURE` や `IF`、`THEN` なんて名前をつけたらどうなるでしょうか?
そのコードを後から読むチームメンバー(あるいは数ヶ月後のあなた自身)は、間違いなく頭を抱え、絶望の淵に立たされることになります。
「動くからいいや」ではなく、「誰が見ても一目で意図がわかる命名」を心がけること。 これが、長年稼働し続けるメインフレームの保守性を守るための、何よりも大切なエンジニアの心得です。
—
まとめ
今回は、PL/Iにおける数値編集文字 `PIC ‘9’` と `PIC ‘Z’` の違いと、それにまつわるちょっとした言語仕様の裏側についてお話ししました。
- `PIC ‘9’` は、桁数をガッチリ固定して先行ゼロをそのまま残す「厳格な番人」。
- `PIC ‘Z’` は、不要な先行ゼロをスマートに消して視認性を高めてくれる「気配り上手」。ただし、末尾には必ず `9` を残すのが実務の知恵!
- 予約語のない自由な世界だけど、コードの可読性を守るために変な名前をつけるのは絶対にNG!
レガシーなメインフレームの世界は、最初は独特の作法に戸惑うことも多いですが、その背景にある「なぜそのような仕様になっているのか」を知るほどに、非常に合理的で頼もしいシステムであることが分かってきます。
「PL/Iって、案外怖くないじゃん!」
そう感じていただけたなら、今回の記事を書いた私としてもこんなに嬉しいことはありません。ぜひ、日々のマイグレーションや保守作業の参考にしてみてくださいね。それでは、また次回のレガシー探訪でお会いしましょう!
