RDML 組み込み関数に関するヒントとテクニック

RDML 組み込み関数の作成当初

RDML 組み込み関数の RDML コマンドは、以下の順序に配置することが推奨されています。

     FUNCTION OPTIONS( *DIRECT … *BUILTIN …)

         任意で、以下のように上書きの BIF 名と記述を続けます。

     DEFINE FIELD(#BIF_NAME) TYPE(*CHAR) LENGTH(20) DESC(<BIF description>) DEFAULT(<BIF name>)

         任意で、以下のように必須の引数、次に任意の引数を続けます。

     DEFINE/DEF_LIST #BIF_ARGnn 

         任意で、以下のように必須の戻り値、そして任意の戻り値を続けます。

     DEFINE/DEF_LIST #BIF_RETnn 

         作業リストの引数または戻り値は常に必要ですので、注意してください。

また、慣習として作業リストの引数カウンター名は BIF_ALCnn、作業リストの戻り値カウンター名は BIF_RLCnn とすることが推奨されています。

LANSA 提供のアプリケーション・テンプレート BBRDMLBIF により生成されたファンクション・スケルトンは、上記の推奨事項に従っています。

戻り値作業リスト

戻り値作業リストは、RDML 組み込み関数の USE コマンド、もしくは RDML 組み込み関数へのエントリーで指定したとしても、自動的にクリアされることはありません。

RDML 組み込み関数内で戻り値作業リストに対して必ず CLR_LIST コマンドを実行するようにするか、エントリーを戻り値作業リストの最後に追加されることをドキュメント化するかのいずれかをRDML 組み込み関数の提供者の責任において選択します。

これを行なうことで、該当の RDML 組み込み関数は戻り値作業リストに対してより柔軟に対応できるようになります。

対話型コマンド

RDML BIF が対話型環境でのみ実行され、RDML BIF のエントリー部分でこの環境に対する適切なチェックがコーディングされることがドキュメントに記されていない限り、RDML BIF のファンクション内で DISPLAY、POP_UP、REQUEST コマンドを使ってコーディングすることは極めて稀です。これは、RDML BIF の移植性にも影響を与えます。

RDML 組み込み関数の終了

*LIGHTUSAGE の RDML 組み込み関数は、使用 (USE) 後に毎回終了されます。

*HEAVYUSAGE の RDML 組み込み関数は、使用 (USE) 後に毎回終了されることはありません。その代わり、この関数を使用しているファンクションが終了時のコントロールを行います。この使用しているファンクションが *HEAVYUSAGE の場合、このプログラムはシャットダウン (EXIT) されるまで終了しません。ですが、シャットダウン時に RDML コマンドは実行されませんので、BIF のシャットダウン・ロジックは実行されません。使用しているファンクションが *LIGHTUSAGE の場合、この BIF に対して終了呼び出しが行われます。このような RDML 組み込み関数には、システム変数 *BIF_SHUTDOWN が 'Y' でないかどうかを確認する評価ロジックを加えることができます。どのような特別なシャットダウンのロジックであっても、*BIF_SHUTDOWN が 'Y' であるかどうかを確認することで、条件付けすることが可能です。

すべての RDML 組み込み関数がシステム変数 *BIF_SHUTDOWN を参照することができます。*LIGHTUSAGE の RDML 組み込み関数の場合、このシステム変数の値は常に 'N' ですので、これが 'Y' の場合の特別シャットダウン・ロジックが実行されることはありません。

RDML 組み込み関数が *LIGHTUSAGE から *HEAVYUSAGE に変更された場合、もしくはその逆の場合、RDML 組み込み関数内にシャットダウン・ロジックが存在する際は、この RDML 組み込み関数を使用するすべてのファンクションを再コンパイルする必要があります。

次の最後の 3 点は重要です。シャットダウン・ロジックの実行は、RDML 組み込み関数が *LIGHTUSAGE なのか *HEAVYUSAGE なのかだけで決定されるものではありません。これを使用しているファンクションが LIGHT なのか HEAVY なのかによっても異なります。RDML 組み込み関数は *LIGHTUSAGE を指定し、シャットダウン・ロジックを持たないことが推奨されています。つまり、*BIF_SHUTDOWN が 'N' の条件が、ファンクション全体に影響することになります。この RDML 組み込み関数がその後 *HEAVYUSAGE に変更された場合でも、この関数を使用しているファンクションは再コンパイルの必要はありません。ただし、呼び出し間に保持されるフィールド値の影響については調査が必要です。この解決策としては、ファンクション内で使用されたすべてのフィールドの初期値を CHANGE/ASSIGN コマンドを使って、常に明確に設定するのが良いでしょう。

*HEAVYUSAGE 組み込み関数をシャットダウンする際のプラットフォームによる違い

C/C++ ファンクションと RPG ファンクションとでは、 *HEAVYUSAGE ファンクションのシャットダウンに違いがあります。(RPG は IBM i の RDML ファンクションに対して生成されますが、C/C++ は、IBM i の RDMLX ファンクションおよび非 IBM i の RDML と RDMLX ファンクションの両方に対して生成されます。)

RPG ファンクションは、シャットダウン時に参照する *HEAVYUSAGE ファンクションをすべてシャットダウンします。

一方 C/C++ ファンクションは、シャットダウン時に実行中に利用した *HEAVYUSAGE ファンクションのみをシャットダウンします。

ですから当然のことながら、*HEAVYUSAGE 組み込み関数のシャットダウンのコードでは、使用されていない場合は呼び出されないということを念頭におく必要があります。

*HEAVYUSAGE の RPG ファンクションは、*LIGHTUSAGE のファンクションがこれを使用しない限り、IBM i のシャットダウンのために呼び出されることはありません。ですから、アプリケーションの再実行時、このファンクションではアプリケーションが前回実行された時と同じ状態が保たれています。ただし、再生リソースが実行されている (RCLRSC) 時は例外です。この場合、状態はクリアされますが、シャットダウンのコードは実際に実行されません。

*HEAVYUSAGE の C/C++ ファンクションは、アプリケーションが終了する時でもシャットダウンのために呼び出されます。

*HEAVYUSAGE 組み込み関数の状態保持

*HEAVYUSAGE ファンクション内で使用されたフィールドの状態は、上記で説明した終了時の動作の影響を受けるため、信頼することはできません。例えば、RDML 組み込み関数が実行される度にある値の数を増加させるとしましょう。*HEAVYUSAGE RDML 組み込み関数は、*HEAVYUSAGE のファンクションが呼び出すと、状態を蓄積できます。ところが、*LIGHTUSAGE ファンクションが使用されるとすぐに、この *HEAVYUSAGE RDML 組み込み関数はシャットダウンされ、状態を失います。

状態を保持する必要がある場合は、データ域もしくはシステム変数を使用してください。

オプションの引数と戻り値

システム変数 *BIF_RETCOUNT の値を確認して、任意の戻り値やその値から導き出された値に条件付きで参照することはよくあります。特に任意の戻り値を取り出す際は、マシンのリソースという観点からするとコストがかかる部分であるため、この方法はより効果的です。

任意の引数が渡されない場合は、デフォルト値となります。任意の引数への参照は、システム変数 *BIF_ARGCOUNT の値を確認することで条件付けることができます。特に、デフォルト値と引き渡された値との区別を付けることができない状況で、異なる処理を行なう必要がある場合は、この手法は必須です。

組み込み関数を使用しているファンクションの USE コマンドにコーディングされているいないに関係なく、任意の引数と戻り値は RDML 組み込み関数内で参照できます。

RDML BIF ファンクションへのアクセス

ファンクションは区画に特有のものです。組み込み関数 (BIF) は LANSA システム全体で利用可能です。RDML 組み込み関数をコンパイルされた場所とは別の区画で使用できるようにするには、その他のジョブに対するライブラリ・リスト内でアクセスできるようにする必要があります。3GL BIF については、LANSA 管理者もしくは BIF 提供者の責任のもと、管理してください。

3GL BIF の RDML BIF への置換

移植性の理由から、3GL BIF を RDML BIF に置換する場合、この BIF を使用 (USE) するすべてのファンクションを再コンパイルする必要があります。これは、3GL と RDML では BIF の基礎となるアーキテクチャが異なるからです。

任意の引数と戻り値の追加

RDML BIF をすでに利用しているファンクションのすべてを再コンパイルすることなく、新規で任意の引数や戻り値を RDML 組み込み関数に追加することが可能です。そのためには、新規の任意引数もしくは戻り値をその他の引数や戻り値の後に追加します。当然ながら、この新規の任意の引数または戻り値を活用するファンクションは再コンパイルの必要があります。ただし、組み込み関数が RDMLX 対応で、どの RDML ファンクションからでも利用できる場合、追加パラメータを加えることはできません。実際には、この RDMLX BIF を使用 (USE) する RDML ファンクションを再コンパイルしない限り、引数や戻り値の数や順番に関連する変更を行なうことはできません。

その他の以下の組み合わせでは問題ありません。つまり、以下のようになります。

クライアント/サーバー環境の RDML BIF

RDML BIF を使って、クライアントからの実行をサーバーへリダイレクトすることができます。この際、アプリケーション側ではこの「構造」についての配慮をする必要は特にありません。