AS/400展望台

V5 BIF が RPG IV で急増



Gary Guthrie 著

フリー・フォーマットの RPG をベースに、V5 組み込み関数(BIF)の数が急増しています。新規 BIF のほとんどが、単純に既存の命令コードと置き換えられるだけですが、フリー・フォーマット・プログラミングを好むか固定フォーマット・プログラミングを好むかにかかわらず、これらの関数はコードを大幅に改善するのです。
ではどのようにして改善するのでしょうか?式を読みやすくすることで改善するのです。

縦欄の命令コード対応部分にあるように、演算項目 1 がこれで、演算項目 2 があれで、結果フィールドはそれといったことはもう必要ありません。より柔軟性があり、直感的に理解しやすく、置き換える RPG 命令コードよりもエラーが少ない式であることは疑いの余地がありません。

日時関連の BIF
Figure 1 に V5 の新規 BIF の一覧が載っています。ほとんどの BIF が日時関連の命令コードとの置き換えであることがわかるでしょう。置き換えなければならない命令コードがあるなら、正に待っていました!といったところでしょう。たとえば、SubDur(期間を減算する)を考えてみます。これは日時またはタイムスタンプから期間を引くことで日時とタイムスタンプを計算する演算ですね。しかしこの関数は、1 つの日時やタイムスタンプを別の日時やタイムスタンプから引くことで期間を計算することもできるのです。この仕様は全く直感的と言わざるを得ません。
いくつかの新しい日時関連の BIF が SubDur や AddDur(期間に加算する)命令コードに取って代わります。以下に示す 3 つの BIF は日付値やタイムスタンプ値に加算または減算できる数を期間に変換します。
・%Years(年数)
・%Months(月数)
・% Days(日数)
また以下に示す 4 つの BIF は時間値やタイムスタンプ値に加算または減算できる数を期間に変換します。
・%Hours(時間数)
・%Minutes(分数)
・%Seconds(秒数)
・%Mseconds(マイクロ秒数)

Figure 2 (Aで示す) のコードは新しい日付を求めるために期間を減算し、新しい時間を求めるために期間に加算している例です。最初のステートメントは、予定返却日から 14 日を引くことで図書館からの本の貸出日を指定しています。2 番目のステートメントは、開始時間に 8 時間を加算することで終了時間を計算しています。BIF は予想通りにきちんと明確なコードになっています。
2 つの日時またはタイムスタンプを減算して期間を計算する SubDur の能力を再現するには、RPG は 3 個のパラメーターを持つ BIF %Diff(2 つの日時値またはタイムスタンプ値間の差分)を追加します。第 1 と第 2 パラメーターは減算する日時またはタイムスタンプの値を指定するオペランドです。これらのオペランドのタイプには互換性が必要です。以下に有効な組み合わせを示します。
・2 つの日付
・2 つの時間
・2 つのタイムスタンプ
・日付とタイムスタンプ(タイムスタンプの日付部分のみ)
・時間とタイムスタンプ(タイムスタンプの時間部分のみ)
第 3 パラメーターは、計算した期間に使用する単位を指定します。以下に有効な値を示します。
・2 つの日付または日付とタイムスタンプ: *Years、*Months、*Days
・2 つの時間または時間とタイムスタンプ: *Hours、*Minutes、*Seconds
・2 つのタイムスタンプ: *Days、*Hours、*Minutes、*Seconds、*Mseconds
計算結果の端数は切り捨てられ、余りは無視されます。たとえば、61 分は 1 時間で、59 分はゼロ時間になるということです。
次に B のコードを見てみましょう。最初のステートメントは、本の貸出日と返却予定日間の日数を計算し、2 番目のステートメントは開始時間と終了時間の間の時間数を指定しています。%Diff を使用するとそれ自身シンプルで明確なコードになることに異論はないでしょう。
%SubDt(日時またはタイムスタンプの一部を抽出する)BIF は命令コード Extrct(日付/時間/タイムスタンプを抽出する)の代替コードです。この BIF には2 個のパラメーターがあります。第 1 パラメーターは情報の抽出元になる日時またはタイムスタンプの値です。第 2 パラメーターは抽出対象部分です。以下に第 2 パラメーターに有効な値を示します。
・日付: *Years、*Months、*Days
・時間: *Hours、*Minutes、*Seconds
・タイムスタンプ: *Years、*Months、*Days、*Hours、*Minutes、*Seconds、*Mseconds

*Days は(ユリウス暦を使用している場合に間違いやすいのですが)その年の日付ではなく、常にその月の日付を参照します。また *Years は、年度を 2 桁で指定していても 4 桁の年度を返します。C に %SubDt の例が2 つあります。最初の例は生年月日から生まれた年を抽出し、次の例は CurTime フィールドに格納された現在時間の時間部分を検索しています。
さらに %Date(日付へ変換する)、%Time(時間に変換する)、%Timestamp(タイムスタンプに変換する)という、3 つの日時関連の BIF があり、これらは文字、数値、タイムスタンプの各値を時間関連の計算に使用できる日付、時間、タイムスタンプの各値に変換します。またこれらの BIF を命令コード Time(日時を検索する)と置き換えることができます。これによりシステム日付とシステム時間をさまざまなフォーマットで検索できます。
これらの BIF にはそれぞれ変換する値と入力フォーマットという 2 個のパラメーターがあります。入力フォーマットとは無関係に、これらの BIF は常に国際標準化機構(*ISO)のフォーマットで情報を返します。最初のパラメーターを指定しないと、ある特定の BIF に合った現在のシステム日時またはタイムスタンプが返されます。D はこれらの BIF の例です。最初の 3 つのステートメントはそれぞれ現在のシステム日付、現在のシステム時間、現在のシステム・タイムスタンプを検索します。次に続く 2 つのステートメントは RPG の予約語 *Date and Udate も使用できることを示しています。これらの値の入力フォーマットはシステムが把握しているため、これらの予約語にはフォーマット・パラメーターは指定しません。このセクションの次のコード例で示すように、タイムスタンプ値のフォーマット・パラメーターも指定しません。最後の2 つのステートメントは入力フォーマット・パラメーターの使用例を示しています。

BIF は探し続ける
配列、テーブル、文字列を検索する BIF もあります。これらの BIF は命令コード LookUp(テーブル・エレメントまたは配列エレメントを探す)、Check(文字をチェックする)、CheckR(逆にチェックする)に置き換わるものです。
命令コード LookUp が提供する関数は %LookUpvxx(配列エレメントを探す)と %TLookUp=xx(テーブル・エレメントを探す)という 2 つのファミリーの BIF に分かれます。xx に有効な値を以下に示します。
・Blank(〜に等しい): 検索引き数にぴったり一致するエレメントを検索します。
・LT(〜より小さい): 検索引き数に最も近いがそれより小さいエレメントを検索します。
・LE(〜以下): 検索引き数にぴったり一致するエレメント、または検索引き数に最も近いがそれより小さいエレメントを検索します。
・GT(〜より大きい): 検索引き数に最も近いがそれより大きなエレメントを検索します。
・GE(〜以上): 検索引き数にぴったり一致するエレメント、または検索引き数に最も近いがそれより大きなエレメントを検索します。
このリストから、配列関数に5 つ、テーブル関数に 5 つの BIF があることがわかります。
BIF の %LookUpxx ファミリーには 4 個のパラメーターがあります。最初の 2 つのパラメーター、検索引き数と検索する配列は必要です。また任意で残り 2 つのパラメーターを指定できます。第 3 パラメーターで検索の開始点を示す指標を指定し、第 4 パラメーターで検索するエレメント数を指定します。デフォルトでは、配列全体が検索されます。これらの BIF は命令で指定されたエレメントの配列指標、または指定した条件に一致するエレメントがない場合はゼロを返します。
%TLookUp にはパラメーターが 3 個あります。最初の 2 つ、検索引き数と検索するテーブルは必要です。オプションの第 3 パラメーターにより、現在のエレメントがそれに続く規則に従って設定される代替テーブルを指定できます。%TLookUpxx 命令が指定した条件に一致すると、BIF は *On を返し、検索テーブルの現在のテーブル・エレメントを条件を満たすエレメントに設定します。また BIF は代替テーブルが定義されていれば、その現在のテーブル・エレメントを同じエレメントに設定します。どのエレメントも %TLookUp 命令が指定する条件を満たさない場合は、*Off を返します。
%LookUpxx および %TLookUpxx は置き換えられる LookUp 命令コードとは二様に異なっています。それは %Equal および %Found で返される演算結果指標、または値を設定しないということです。
Figure 3 に BIF の %LookUpxx および %TLookUpxx ファミリーの例をいくつか示しています。A で示すコードは %LookUp を使用して、検索引き数 SrchArg に含まれる値にぴったり一致する値を探して配列全体 (SomeAry) を検索します。戻された指標の非ゼロ値は、指定した検索条件で一致する値が見つかったことを示しています。
この例の特異性を見てみましょう。%LookUp では第 3 パラメーターは検索を開始するエレメントを指定します。B の例では第 4 エレメントから検索が始まっています。%LookUp を使用する場合は、検索するエレメント数さえ指定できるのです。C のコード例はエレメント 4 から 8(5 個のエレメントに対して第 4 エレメントから始まっている)までだけを検索しています。LookUp 命令コードには同等の関数はありません。
D の例は A と同じですが、検索条件が「〜以上」になっています。E では %TLookUp は「〜より小さい」条件を使用してテーブル TabEmp を検索しています。このステートメントをよりわかりやすくした例が F です。
項目の存在を検索する命令を見てきましたので、今度は基本的に項目が存在しないことを検索する 2 つの命令に注目してみましょう。%Check(文字をチェックする)と %CheckR(逆にチェックする)BIF は基本ストリングの文字が、コンパレータ−・ストリングで指定した文字中にあるかどうか検証します。両方ともパラメーターとして以下を持っています。
・Comparator string ? 固定または可変長の必須パラメーターで、文字、図形、Universal Multiple-Octet Coded Character Set (UCS 2) を入力します。
・Base string ? 第 1 パラメーターとタイプが同じでなければならない必須パラメーターです。基本ストリングは検証する文字を指定します。 ? Starting position ? 任意のパラメーターでゼロ小数点位の非浮動数値です。基本ストリング内の開始位置を指定します(デフォルトは 1 )。
%Check は基本ストリングの開始位置で始まり、コンパレータ−・ストリングにない文字を見つけるまで左から右へ文字をチェックします。%CheckR も機能は同様ですが、右から左へと文字をチェックします。BIF は基本ストリング内の文字の位置を返し、命令を終了させます。基本ストリング中のすべての文字がコンパレータ−・ストリングにある場合は、ゼロ (0) が返されます。
Figure 4 はこれら BIF の使用例です。A のコードは %Check の一般的な使用例を示しています。コードのこのセクションは文字列 SomeString 中の最初の非ブランク文字を見つけます。B でも同じようなチェックが行われますが、プロセスは SomeString の 11 番目の文字から始まっています。C では %Check は SomeString 中の数字でない最初の文字を見つけています。D と E の例では %CheckR を使用して、文字列の最後(または指定した開始位置)から右から左へとプロセスを実行しています。

BIF のアラカルト
ここでその他の BIF を加えると新規 BIF のリストが完成します。どのカテゴリーにも属さない BIF なので、ここでそれらをまとめて説明しましょう。
%Occur(データ構造のオカレンスを設定・取得する)BIF はデータ構造の現在のオカレンスを設定または取得します。パラメーターは 1 個で、データ構造名です。(Figure 5の A で示すように)割り当て演算の左側でそのパラメーターを使用する場合は、%Occur は現在のオカレンスを設定します。(Bで示すように)右側で使用する場合は、現在のオカレンスを検索します。
文字列中の文字をある値からユーザーが提供する変換情報に基づいた値に変換したい場合があるでしょう。その場合は %Xlate(変換)BIF がぴったりです。この BIF には 4 個のパラメーターがあります。第 1 パラメーターは置き換える文字列のリストです。%Xlate の第2 パラメーターには第 1 パラメーターからの文字が文字列内に見つかった場合に使用する置き換え値が入っています。第 1 パラメーターで指定する各文字について、第 2 パラメーターで置き換え値を指定します。第 3 パラメーターは、%Xlate が変換する文字を含む文字列です。第4 パラメーターは任意で、文字列内に変換の開始位置を含んでいます(デフォルトは 1)。
C のコードは小文字を大文字に変換するというこの BIF の典型的な使用例です。この例では、Lower フィールドに a から z の値が入っていて、Upper フィールドに対応する A から Z の値が入っています。D のコードは同様の例ですが、文字列の最初の 10 文字は変換していません。
%SqRt(式の平方根)BIF は数式の平方根を返します。パラメーターは 1 個で、平方根を計算する数式の数を指定します。このオペランドが浮動タイプなら結果も浮動タイプ、それ以外の場合は結果はパック式になります。おわかりのとおり、このオペランドに負の数を指定すると、例外になります。E のコードはこの BIF の例です。
その他にメモリー管理用の BIF があります。%Alloc(ストレージを割り当てる)と %ReAlloc(ストレージを再割り当てする)の2 つです。%Alloc はユーザー指定のヒープ・ストレージ量を割り当て、そのストレージに対するポインターを返します。パラメーターは 1 個で、割り当てるストレージの長さを示す数を示します。この数字はゼロ小数点位の非浮動数値で、1 から 16,776,704 までの値である必要があります。F は %Alloc の使用例を示しています。
いったンストレージを割り当てたら、%ReAlloc を使用して割り当てた量を変更できます。この BIF には2 個のパラメーターがあります。第 1 パラメーターはストレージに対する現在位置で、第 2 パラメーターは %Alloc の長さパラメーターと同じ規則に従う新しい長さです。%Alloc 同様 %ReAlloc もストレージに対するポインターを返します。このポインターは新しいポインターか、現在のポインターと同じになります。G では、%ReAlloc は前述の例で割り当てた量を変更しており、もとのポインター・フィールドにポインター値を返しています。
%ShtDn(シャットダウンする)BIF(H に示す)を使用すると、ユーザーがシステムをシャットダウンする要求を出したかどうか判断できます。この BIF にはパラメーターがなく、ブール指標を返します。'1' という値はシャットダウン要求が発行されたことを示します。
Java と RPG を統合するユーザーが気をつけなければいけないのは、%This(ネイティブ・メソッドにクラス・インスタンスを返す)BIF を追加しなければならないことです。この BIF は Java の予約語 this に対する RPG の応答になります。%This はネイティブ・メソッドが呼ばれている原因となっているクラス・インスタンスへの参照を含む Object 値を返し、非静的メソッドによるクラス・インスタンスへのアクセスができます。I のコードは同じクラスで別のメソッド SomeMethod を呼び出すメソッドからのステートメントを示しています。

%End 終わりに
多くのプログラマーが固定フォーマットの RPG でアプリケーションを作成しているために、新しい BIF の固定フォーマットの例を示すことにしました。固定フォーマットでのコーディングを推奨しているのではなく、その BIF を強調したほうがコードを理解しやすいと思ったからです。フリー・フォーマットの RPG で BIF を使用し始めたら、コードが格段にわかりやすくなることは間違いないでしょう。

ゲーリー・ガスリー。iSeries NEWS の上級テクニカル・エディターおよび iSeries のテクカル・サポート・コンサルタント。



↑このページのトップへ
TOPPAGE

BELLDATA, Inc. Copyright reserved.