現場のPL/I職人が教える「空白除去」の罠と、TRIM/LEFT/RIGHT関数の極意
こんにちは。メインフレームの現場で何十年とバッチプログラムの波を乗り越えてきた者です。
今日は、若手エンジニアから「なぜか期待した通りに文字列が切り取れない」という相談を受けることが多い、`TRIM`、`LEFT`、`RIGHT`といった文字列操作関数について深掘りしましょう。特に、我々が扱うEBCDIC環境では、単純な「スペース」の定義が思わぬ落とし穴になることがあります。
1. なぜPL/Iには「予約語」がないのか?
まず前提として、PL/Iの「予約語が存在しない」という設計思想について少し触れておきましょう。`IF`や`THEN`、あるいは`TRIM`といった関数名であっても、PL/Iでは変数名として宣言できてしまいます。
「え、じゃあコンパイラはどうやって判断するの?」と驚くかもしれませんが、PL/Iは文脈(コンテキスト)で判断します。だからこそ、我々保守担当は、「組み込み関数(Built-in Function)と同じ名前を変数名に使うな」という鉄の掟を守らなければなりません。もし`TRIM`という名前の変数を作ってしまったら、そのスコープ内では組み込み関数の`TRIM`は使えなくなり、バグの温床になります。
2. TRIM関数:空白除去の真実
`TRIM(文字列)`は非常に便利ですが、EBCDIC環境で開発している皆さんは、対象が「X’40’(スペース)」であることを常に意識してください。
`TRIM`はデフォルトで、文字列の両端からスペースを取り除きます。しかし、例えばVSAMファイルから読み込んだ固定長レコードのパディングが、X’00’(NULL)や他の制御コードで埋められている場合、デフォルトの`TRIM`では太刀打ちできません。
1
/ VSAMレコードから読み込んだ可変長項目のクリーニング例 /
DCL WS_DATA CHAR(50) VARYING;
DCL WORK_STR CHAR(50) INIT(‘ ABCDEF ‘);
/
- 第2引数に削除したい文字を指定することで、スペース以外の
- パディングにも対応可能です。これが実務の知恵です。
/
WS_DATA = TRIM(WORK_STR, ‘ ‘);
/ X’00’を削除したい場合は、HEX値を指定してこう書く /
WS_DATA = TRIM(WORK_STR, ’00’X);
3. LEFT/RIGHT関数の「詰め物」とパフォーマンス
`LEFT(文字列, 長さ)`と`RIGHT(文字列, 長さ)`は、文字列を切り詰めるだけではありません。指定した長さが元の文字列より長い場合、右側(または左側)にパディングを補完する役割も持っています。
ここで注意すべきはパフォーマンスです。数百万件のレコードを処理するバッチで、ループの中で頻繁にこれらの関数を呼び出すと、CPU使用率が跳ね上がります。
1
DCL NAME_FIELD CHAR(20);
DCL OUTPUT_REC CHAR(50);
/ 名前を左詰めにし、残りをスペースで埋める /
/ 20桁に満たない場合は、右側にスペースが自動付与される /
OUTPUT_REC = LEFT(NAME_FIELD, 20);
/
- 逆に、数値データを右詰めにして0埋めしたい場合は、
- LEFT/RIGHTだけでなく、EDIT関数を組み合わせるのが定石。
/
4. トラブルを未然に防ぐ「ONユニット」との付き合い方
文字列操作に関連して、データ変換エラーや領域外参照(Subscript range)が発生した際、`ON FIXEDOVERFLOW`や`ON STRINGRANGE`を適切に定義していないプログラムをよく見かけます。
基幹システムのバッチでは、異常発生時に「何が起きたか」をログに出して適切に終了することが求められます。
1
/ 実行時エラーを捕捉するためのONユニット設定例 /
ON STRINGRANGE BEGIN;
PUT SKIP LIST(‘文字列範囲外のアクセスを検出しました。ログを確認してください。’);
CALL ABEND_ROUTINE; / 自作の異常終了処理 /
END;
現場からのアドバイス:保守性のために
最後に、ベテランとしてのアドバイスです。
1. 関数の入れ子を避ける: `TRIM(LEFT(A, 10))`のように関数を多段に入れ子にするのはやめましょう。デバッグ時に値の推移が追えなくなります。中間変数を用いて、一段階ずつ処理を記述してください。
2. 定数の定義: スペース以外の文字をトリミングする際、その文字コードをハードコーディングしないでください。`DCL PAD_CHAR CHAR(1) INIT(’00’X);`のように定数宣言し、名前を付けましょう。
3. VSAMアクセスの前後で必ずクリーニング: ファイルから読み出した直後のデータには、予期せぬゴミデータが混入していると仮定してください。`TRIM`による正規化を読み込み直後に行うのが、安定したシステム構築の第一歩です。
PL/Iは古い言語ですが、その仕様は非常に論理的で強力です。皆さんが扱っているそのコードは、何十年も日本の社会インフラを支えてきた誇り高い遺産です。自信を持って、堅牢なコードを書いてください。
また何か壁にぶつかったら、いつでも聞きに来てください。現場からは以上です。
