作成する方法を解説しました。金額を引数で受け取り、税込価格を戻り値として戻す簡単な関数の作成を通して、サービス・プログラムの基本はおおよそ理解していただけたと思います。複数のプログラムで共通で使用するロジックがあれば、サービス・プログラムにユーザー関数としてまとめておくことにより、プログラム作成者はその関数を各プログラムから呼び出すだけで、ロジックを知らなくても結果を取得することができるようになります。引数や戻り値が変わらないのであれば、サービス・プログラムの更新だけで、それを使用するプログラムは一切変更せずにロジックを修正することができることも解説しました。保守しやすいシステム実現にサービス・プログラムが有効であることを理解していただけたと思います。今回は、このサービス・プログラムをさらに詳細に解説していきます。修正の際の考慮点、プロトタイプ定義の共通化などを取り上げます。なんら変更することなく実行することができましたね。とこの関数との接点である引数と戻り値を何も変更していないからです。内部ロジックを見えないようにカプセル化し、外部との接点を最小限にしておく、この疎結合の考え方がお互いを独立させ保守の容易性を飛躍的に高めているのです。変更した税率を有効にするにはサインオンし直して、再度プログラムを実行しなければなりませんでしたね。してサービス・プログラムの更新がすぐに有効にならないのでしょうか?この理由を明らかにするには、バインディング処理の理解が必要です。プログラムの基本構造」で解説した通り、サブ・プロシージャーは静的呼び出しで実行されます。ユーザー関数もサブ・プロシージャーなので、呼び出しは静的呼び出しです。この呼出しは各関数のアドレスを使用して行われるのですが、この一連のアドレス解決をバインディング処理といいます。実際のバインディング処理は以下の通りです。関数を呼び出すプログラムは、それぞれの関数をこのアドレスを使って呼び出します。コマンドによる動的呼び出しと比較して、アドレスによる呼び出しは高速に実行可能です。動的呼び出しは、毎回オブジェクトの検索(ライブラリーを特定するか、ライブラリー・リストの先頭からオブジェクトを検索)をするため、呼び出しごとの負荷は避けられません。いう名前の活動化グループ内で実行されます。サービス・プログラムがメモリーにロードされるタイミングは、先ほど解説した通りそれを呼び出すプログラムが活動化されるときです。サービス・プログラムの活動化は1つの活動化グループ内で1回だけです。名前付きの活動化グループは、明示的に削除しない限り、プログラムが終了しても存在しており、同じプログラムが実行されると再利用されます。最初に実行した時にアドレス解決したサービス・プログラム内の関数(メモリー上にロードされているもの)は、その活動化グループが再利用される限りずっと使われることになります。プログラムから使用されるためにメモリーにロードされたサービス・プログラムを更新するとどうなるのでしょうか。ヘルプを見てみましょう。「サービス・プログラムがこのコマンドによって置き換えられている間であっても、結合サービス・プログラムを実行中の他のジョブは実行することができます。現在実行中のサービス・プログラムはライブラリーQRPLOBJに移動され、サービス・プログラムの更新済みバージョンがサービス・プログラムのライブラリーに挿入されます。サービス・プログラムの現在の活動化は、QRPLOBJライブラリー内のサービス・プログラムのバージョンを使用して実行し続けます。オブジェクトは更新できるが、実行中のプログラムは前のバージョンが使用されるということです。これが前回サービス・プログラムを修正して税率を変更したのに、その修正が変更後のプログラム実行に反映されなかった理由です。サービス・プログラムを修正し、かつそのサービス・プログラムが活動化されていたら、該当の活動化グループを再作成する必要があるのですね。名前付きの活動化グループを削除する方法は以下の2通りです。コマンドを使用する今後サービス・プログラムの修正をしたが、変更が反映されないケースの場合は、サインオンし直すか、以下コマンドを実行してください。呼び出すために、プロトタイプ定義が必要でした。これは、コンパイラーにプログラム内で呼び出す関数名、引数の数とそれぞれの属性、戻り値の型を知らせる目的で記述します。オブジェクトを作成しません。パラメータ)したサービス・プログラム内に呼び出す関数が存在しているかのチェックは行いますが、引数や戻り値についてはチェックされません。これを記号解決(名前解決)といいます。使用している関数名がサービス・プログラム内に存在しているかチェックそれぞれのステップで何が行われているかを理解することは重要です。プロトタイプ定義と、サービス・プログラムに定義されている実際の関数の引数や戻り値は異なっていても、名前さえ一致していればプログラムは作成できるのです。この場合、作成されたプログラムを実行すると、実行時エラーとなってしまうのですが。このプロトタイプ定義はプログラマーにとってはかなりの負担になります。実際のサービス・プログラムの定義通りにプロトタイプ定義をコーディングしておかなければ実行時エラーの原因になるからです。通常は複数の関数を使用することになるため、プログラムごとのプロトタイプ定義は相当のステップを占めることにもなります。サービス・プログラムを利用する際の大きな障壁になっているように思います。この問題はどのように解決していけば良いのでしょうか。コーディングの煩雑さに関しては定義を一箇所にまとめ、それを各プログラムがコピーすることで解決します。定義はサービス・プログラムの作成者が行うべきです。作成者ですから関数名はもちろん、引数や戻り値の情報を熟知しているからです。そこで通常は以下の手順でこの問題を解決します。記述するこうすることにより、プログラマーはサービス・プログラムの作成者が記述した個別のプロトタイプ定義を、意識することなくコンパイル時にソースに組み込むことが可能になり、個別にコーディングする負荷がなくなります。これは、プログラム・ソースにコンパイル時にコピーするものなので、単独でコンパイルはしません。組み込むように変更しましょう。記述すると、その箇所に指定したファイル(./prototype.rpgle)がコンパイル時に挿入されます。ファイル名の前の「./」はカレントディレクトリを意味します。この共通ファイルをどこに置くかでこの記述方法を変更しなければならない点については注意しておきましょう。それではプログラムを再作成します。指定)問題なくモジュールのコンパイルができたと思います。記述を再確認しましょう。次にプロトタイプ定義の正しさを保証する点について考えましょう。実は、プロトタイプ定義における関数名、引数や戻り値のコンパイル時のチェックは、関数を呼び出す側のプログラムだけでなく、ユーザー関数を含むモジュールのコンパイル時にも本来は必要なものです。プロトタイプ定義がなくてもコンパイルはできていたのです。作成したので、サービス・プログラムを構成するモジュールにもこれを組み込むようにすれば、プロトタイプ定義と実際の関数の定義の乖離を極力防ぐことができるようになります。手順は以下の通りです。組み込んでモジュールおよびプログラムを作成する・プロトタイプ定義は実際の関数と一致しているので実行時のエラーを防げる因みに、そのモジュール内で使われていない関数に対するプロトタイプ定義が存在してもコンパイルには何ら影響しませんので、プロトタイプ定義用ファイルにはすべてのプロトタイプ定義を含めるようにしましょう。1)を使用していました。使用して作成しました。言語の本来の作成手順は後者であることを今一度認識しておいてください。それは、プログラムを作成するプログラマーが、使用するサービス・プログラムがどのライブラリーにあるのか、名前が何かなどの情報を知らないと作成できないということです。プログラマーは使用したいユーザー関数情報は知っていますが(知らなければコーディングできない)、その関数がどのサービス・プログラムにあるのかまでは知らないかもしれません。この問題を解決するために利用可能なのがバインド・ディレクトリです。実行時に行われるのは名前解決でしたね。されているかをチェックすることで実現します。この名前解決に使用するサービス・プログラムを予めリスト化しておき、プログラム作成時に利用するために用意されているのがバインド・ディレクトリというオブジェクト(*BNDDIR)です。関連コマンドは以下の通りです。CRTBNDDIR(バインド・ディレクトリの作成)ADDBNDDIRE(バインド・ディレクトリ項目の追加)DSPBNDDIR(バインド・ディレクトリの表示)今回は以下のコマンドを使用してすでに皆さんのライブラリーに作成済です。実行すると、以下の画面が表示されます。コマンドを押してすべてのパラメータを表示し、次ページを表示すると以下の画面が表示されます。バインド・ディレクトリを指定すればサービス・プログラム名を個別に指定する必要はありません。名前解決はバインド・ディレクトリに登録されているサービス・プログラムを順番に検索することで実施します。オブジェクトを探索するのにライブラリー・リストを使用するのと似ています。バインド・ディレクトリはサービス・プログラム作成者が保守し、プログラマーはバインド・ディレクトリ名だけを知っていいれば良いことになりますね。コマンドにも存在します。コマンドで作成することもできるわけです。内の制御ステートメントで以下の記述を追加すれば、プログラムの作成が可能です。作成できることを確認しましょう。内のバインド・ディレクトリ名はライブラリー名の修飾も可能なので引用符で囲む必要があります。大文字小文字を区別しますので、ここでは必ず大文字で定義するようにしてください。終わりに前回に引き続き、サービス・プログラムを解説しましたがいかがだったでしょうか。今回は解説が多く、プログラムの新規作成はなかったので分かりづらかったかもしれません。実際の基幹システムでサービス・プログラムを活用する場合は、今回の解説内容は最低限理解しておかなければならないことだと思っています。何度も読み返してしっかり理解するようにしてください。サービス・プログラムについては、まだ解説しなければならないことがあります。次回は上記の解説と、日付から曜日を算出するユーザー関数を作成する予定です。お楽しみに!著者プロフィールこの記事のあとにはこちらの記事もおススメです。通信プロトコルフリーワード検索お探しの情報に関する単語を入力してください。iに関するさまざまな資料を掲載しています。お探しの資料をぜひさがしてみてくださいね。