【PL/I学習|豆知識】メインフレーム開発の知恵袋:GENERIC属性で「型」の壁を越えるスマートなAPI設計

導入:なぜGENERIC属性が必要なのか

メインフレームのPL/I開発において、数値の型(FIXED BINやFIXED DECなど)ごとに異なる計算ロジックを用意しなければならない場面は多々あります。呼び出し側が毎回「これはBINARYだからこの関数を呼ぶ」と意識するのは非効率ですし、保守性も低下します。そんな課題を解決するのがGENERIC属性です。これを活用することで、呼び出し側はただ一つの名前を呼ぶだけで、コンパイラが自動的に適切なプロシージャを選択してくれるようになります。

基礎知識:GENERIC属性とは何か

GENERIC属性は、一言で言えば「コンパイル時に選択されるプロシージャの振り分け機能」です。現代のJavaやC++における「メソッド・オーバーロード」の先駆けとも言える仕組みです。プログラマが明示的に呼び出し先を分けるのではなく、引数の属性(型や精度)に基づいて、最適な関数をマッピングします。これにより、APIを一貫した名称で提供でき、コードの可読性が格段に向上します。

実装:GENERIC宣言の構成方法

GENERICの定義には、呼び出しの窓口となる名前と、条件に応じた振り分け先を指定します。DCL文で「GENERIC(対象1 WHEN(条件1), 対象2 WHEN(条件2))」と記述するのが基本です。コンパイラは、呼び出された引数の型がどの条件に合致するかを上から順に判定し、一致したプロシージャをコンパイル時に静的にリンクします。

サンプルプログラム:数値の絶対値を返す汎用API

以下に、FIXED BIN型とFIXED DEC型を自動判別するサンプルコードを提示します。

/ 呼び出し側のインターフェース定義 /
DCL MY_ABS GENERIC(
    ABS_BIN WHEN (FIXED BIN),
    ABS_DEC WHEN (FIXED DEC)
);

/ 処理の実装部 /
ABS_BIN: PROC(P_VAL) RETURNS(FIXED BIN);
    DCL P_VAL FIXED BIN;
    IF P_VAL < 0 THEN RETURN(-P_VAL);
    RETURN(P_VAL);
END ABS_BIN;

ABS_DEC: PROC(P_VAL) RETURNS(FIXED DEC(15,2));
    DCL P_VAL FIXED DEC(15,2);
    IF P_VAL < 0 THEN RETURN(-P_VAL);
    RETURN(P_VAL);
END ABS_DEC;

/ 利用例 /
DCL VAL_B FIXED BIN := -10;
DCL VAL_D FIXED DEC(15,2) := -123.45;
DCL RESULT_B FIXED BIN;
DCL RESULT_D FIXED DEC(15,2);

/ 同じ名前のMY_ABSを呼ぶだけで、型に応じて適切なプロシージャが選択される /
RESULT_B = MY_ABS(VAL_B);
RESULT_D = MY_ABS(VAL_D);

応用・注意点:現場での運用ポイント

現場でGENERIC属性を使う際、特に注意すべきは「型の一致条件」です。
1. 厳密な型チェック:WHEN句で指定した型と、実際の引数の型が微妙に異なると(例えばDECの精度が異なる場合など)、コンパイラが一致するプロシージャを見つけられずエラーになることがあります。必要に応じて属性を明示的にキャストする習慣をつけましょう。
2. デバッグの難しさ:GENERICはコンパイル時に解決されるため、実行時の挙動を追う際に「どのプロシージャが選ばれたのか」がソース上だけでは直感的に分かりにくい場合があります。複雑な分岐をさせすぎないのが、保守性を保つコツです。
3. 将来の移行を見据えて:JavaやC++への移行プロジェクトでは、このGENERICの構造をそのままクラスのメソッド・オーバーロードへ変換できるため、設計段階からこの書き方を踏襲しておくことは、将来的な近代化の際にも非常に有効な資産となります。

コメント

タイトルとURLをコピーしました