RPGの虜!
本稿のタイトルは2通りに解釈できます。私が本当にRPGのことが大好き(「私が虜になっている」)という意味と、皆さんがRPGを使用するときに従うべき必要なポリシー(「ルール」)を私が提供したいという意味です。さてどちらの意味だと思いますか。実は両方なのです。本稿では、私がRPGという言語をなぜ好きなのかという理由だけではなく、RPGを使用して開発するアプリケーションをよりモダンなものにするために従うべきルールについても説明します。
RPGはすばらしい言語です。私はRPGが大好きです。しかしRPGは決して新しい言語ではありません。40年間に渡る進化の結果なのです。私の考えでは、RPGはビジネス・ルールを記述するのに世界最良の言語だと思うのですが、同時に、下位互換性を保つためのたくさんの古い機能もサポートし続けています。こうした古い機能は「レガシー機能」と呼ばれており、今となってはそれを使用して厄介なことにならないようにすべきです。
RPGはなぜ我々を虜にするのか
RPGはレガシーなものではありますが、特にSystem iファミリーのコンピュータ(およびその旧型)用のビジネス・アプリケーションを記述するための言語として開発されたことにより、今日における最良の開発言語の1つになっています。他のプラットフォーム上で他の言語を使用してビジネス・アプリケーションを記述してみなければ、RPGが持っている価値を正しく認識するのは難しいでしょう。新しい言語というと響きは良いですが、実際に使用してみるとRPGが持つ優雅さに欠けていることに気づくことが多いでしょう。RPGが我々を虜にする理由を短いリストにまとめてみました。
簡素さ
私は単にビジネスを運営したいだけなのです。その背後にあるテクノロジーについては気にしていないのです。そのテクノロジーがうまく機能していていることで私はビジネスに集中したいだけなのです。
適切な10進数処理のサポート
ビジネスは10進数の計算上に成り立っています。あらゆるプログラミング言語は組み込み式のうまく統合された整数および浮動小数点演算をサポートしていますが、真の意味での10進数タイプのサポートについてはそのレベルがさまざまです。たとえば、整数データが分数をサポートしていない、浮動小数点が近似値や丸めを使用していて10進数データの処理時にエラーを起こす、などです。ゾーン10進数やパック10進数などといった真の意味での10進数タイプはまさにビジネス上で必要な計算を処理するものです。これらを使用すると数量、重量、通貨などの値を容易に加算することができます。RPGでは、10進数の演算は自動的に行なわれます。10進数かどうかなどを気にする必要はなく、とにかくきちんと処理されるのです。他の言語では真の10進数サポートを利用するために特別なAPIを呼ぶか、10進数演算を使用せずに浮動小数点や整数タイプの欠点を回避しなければならないというものが多いようです。
適切なエラー処理
RPGの演算が失敗に終わるとエスケープ・メッセージが送られてきます。そうしたエラーをトラップして処理するコードを書かないとプログラムがクラッシュします。他のプログラミング言語の一部ではこの機能がありません。こうしたプログラミング言語のコア機能はプログラムのエラー・フィールドにエラーを返してくるので、そのエラーをチェックするためのコードを追加して記述しなければなりません。またこうしたプログラミング言語では、エラーをチェックして処理しないとプログラムはあたかも何も悪い事が起こらなかったかのように実行を続け、あとになって真の原因が突き止めづらいようなはっきりとしない問題を引き起こすことになります。エラーを無視するというデフォルトの動作のままにしておくと、原因を突き止められない異常を引き起こす問題の原因となり、再インストールやリブートといった解決策しかないといった事態に陥ります。RPGプログラムでそのような事態に陥ったことはどれくらいありますか。
データベースとの密な連携
ビジネス・アプリケーションはたくさんのデータベース・ロジックを使用する場合が多いです。RPGは元々オペレーティング・システムの組み込みデータベースを最も自然でしかも簡単な形で使用する言語として設計されています。データベースからレコードを取得したい場合は、そのレコードを読み込む文を記述すればおしまいです。もっと複雑なSQL文をRPGプログラム中に記述したい場合でも、そのSQL文を記述して、データをどのRPG変数名に挿入または返すか指示するだけです。それくらい簡単なのです。他の言語ではSQL用の複雑なAPI関数群を呼び出さなければなりません。また、単純な変数名ではなく通常のSQLカラム番号を使用しなければならない言語もあります。
オペレーティング・システムとの密な連携
i5/OSはこの世で最高のオペレーティング・システムです。その安定性、テクノロジー独立性、仮想化エンジン、ワーク管理機能、診断機能、セキュリティ、統合データベースなどにより、世界最良のツールの1つとなっています。i5/OSで利用できるプログラミング言語はたくさんありますが、そのほとんどは他のオペレーティング・システムでも利用できます。開発したプログラムが他のオペレーティング・システム上でも実行することができるのであれば、オペレーティング・システムのパワーを本当の意味で利用するにはどうしたらよいのでしょうか。CobolやCはANSI標準に準拠しなければなりません。Java、PHP、PerlはすべてSystem i上で実行できるのと同様に他のプラットフォームでも同じように実行できます。RPGとCLだけがi5/OS用に設計されており、i5/OSと密に連携されていますので、i5/OSの機能を完全に活用することができます。
ジョブ・ログ
ジョブ・ログは本来はオペレーティング・システムと連携している部分になりますが、他のプログラミング言語やプラットフォームで開発する際に良く忘れるのがこの機能であるため、わざわざ別のトピックとしました。私はi5/OSのジョブ・ログが本当に気に入っています。WRKACTJOBディスプレイを表示させ、エラーを起こしているジョブを選択し、そのジョブのジョブ・ログを表示させて何が起こったのかをすべて表示させることができるので高く評価しています。もちろん他のプラットフォームにもログ機能はありますが、どのプログラミング言語もそれぞれ異なるログ機能を異なる方法で使用しているのです。i5/OSにネイティブな言語の多くがRPGと同様にジョブ・ログを使用しているのは認めますが、ジョブ・ログを使用していないものもあり、それは私にとっては大変大きな意味を持つことなのです
将来への互換性
CLを除けばRPGはIBMがその運命を完全にコントロールしている唯一の言語です。RPGは、今日書いたプログラムを5年、10年後に同じシステム上でコンパイルして実行できるということが長年にわたって証明されているのです。RPGの上位互換性を保つという点においてIBMは見事な仕事をしたわけです。会社が開発費をRPGに投資すると、その投資が長年にわたって報われるというということになります。今日現在RPGプログラマが保守しているアプリケーションを眺めてみて、もしそのアプリケーションが他の言語で記述されていたとしたら今でもそのアプリケーションが使われていたかどうか自問してみてください。ただ残念なことに、上位互換性は両刃の剣でもあります。RPGプログラムは何も修正を加えなくても実行し続けるがゆえに、プログラマは自分の実績に胡座をかいて古くなったテクニックやレガシーのテクニックを新しいものに置き換えていくことを怠りがちになります。そうした怠慢により業界が停滞していくのです。これが私の言う両刃の剣なのです。
RPGで開発を行なう際のルール
アプリケーションを更新しなかったりテクノロジーを向上させなければ時代に取り残されます。残念なことにそれはSystem iの業界でもあちこちで起こっています。アプリケーションが全く正常に動作する場合が多いがために、プログラマは10年も15年も前と同じ方法でコードを書きつづけ、その結果RPGは新しい機能を提供できないと考えてしまう人が多くなってしまっているのです。実際、RPGといえば5250の緑色の画面と、まるでこの両者が連れ合いであるかのような連想をする人が多数いるのです。こうした誤解を解く唯一の方法はRPGは緑色の画面以上のたくさんのことができるということを示すしかありません。そしてそれを示すにはプログラムを更新するのが最善の策です。
これから説明するのは今の時代にRPGプログラムを記述する際に使用していただきたいルールの一覧(これがすべてというつもりはありませんが)です。
ビジネス・ロジックとデータベース・ロジックの隠蔽
コードを「隠蔽」するときはそのコードを隔離してそれがどのように動作しているかを見えなくします。ここでの基本的な考え方はサブ・プロシージャを呼び出しているプログラムはそのプロシージャがどのように動作しているのかを知るべきではないし、心配する必要もないということです。プロシージャの動作を全く違ったものに変更しながらもパラメータのリストは変えずにおけば、そのプロシージャを呼び出す側は変更があったことなど知らなくても動作します。たとえば、retrieveItemPrice()というプロシージャがある場合、それを呼び出す側のルーチンは商品の価格を格納する物理ファイルがどこにあるのかわからなくても良いはずですし、データベースを使っているのかどうかさえ知らなくても良いはずです。おそらく5年も経てば価格ファイルを使う代わりに、インターネットから取得した原材料の市場価値を足し加えていって計算するようになるでしょう。コードを隠蔽すると、呼び出し側を変更したりすべてテストし直したりしないでコードを変更できるのでコードの保守に必要なコストを削減できます。コードを隠蔽することでビジネスの変化に応じたコードの変更が容易になります。
ビジネス・ロジックと表示ロジックを決して混在させない
ビジネス・ロジックはビジネスがどのように運営されていくのかをコントロールするためのロジックです。データがどのように格納されるか。フィールドに格納してもよい値はどれか。価格はどのように計算するのか。費用を総勘定元帳にどのように適用するのか。などといたことは、ユーザーに対して画面をどのように表示させるかとは全く別のことです。ユーザー・インタフェースはビジネス・ロジックから分離してください。あとになって表示のためのテクノロジーを変更したくなるかもしれないからです。現在緑色の画面を使用している場合、近い将来にウェブまたはGUIを使用したくなるかもしれません。または、SQL文やウェブ・サービスからビジネス・ロジックへアクセスできるようにしたくなるかもしれません。コードを書き直さなくても見た目を新しくできるようなコードにしておいてください。
融通の利かないプログラムではなく豊富なサービス・ライブラリを提供する
自社のビジネス・ロジック専用の独自のプログラミング言語を作り上げるとなったとしましょう。その言語はどのようなopcodeを提供しますか。おそらくCreateOrder、AddItem、DisplayOrder、InvoiceItems、MarkPaidなどといった名前のopcodeを作ることになるでしょう。アプリケーションを設計する際は、他の部分とは独立して1つのことを実行する比較的単純なルーチンを複数個用意するように設計してください。そうしておけば、こうしたルーチンを単に呼び出すだけで全体のアプリケーションを開発できるはずです。他のプログラミング言語からも呼び出せるようにしておけば、将来どのようなことになってもこのツールを再利用しつづけることができます。
CALL/CALLB/PARMではなくprototypeを使用する
私はいつも他人が書いたRPGのコードにCALL、CALLB、PLIST、PARMなどといった古いopcodeがあるとびっくりしてしまいます。こうした古いopcodeでできることはすべてprototypeでもできます。しかも過去11年に渡り、プログラム、プロシージャ、メソッドなどの呼び出しに関する部分の機能強化はprototypeに対してだけ行なわれています。ルーチンを呼び出す方法として古い方法を使用することに固執していると、いつまでも20世紀の世界にとらわれ続けることになります。
配列ではなく文字列操作を使用する
RPG IVがリリースされるまでは、RPGでは適切な文字列処理ができませんでしたので、プログラマは文字列を1Aフィールドの配列に移してその配列を使って文字列の操作をしていました。しかし、この方法は1995年以降不要になっています。皆さん、この方法をまだ使っているのを見るたびに私は心が痛むのです。
ADD/MULT/SUB/DIVではなく式を使用する
今日のRPGプログラムではあらゆる算術演算用の式が使えます。ADD、MULT、SUB、DIVなどといったレガシーのopcodeを使う必要はもうありません。
サブ・ルーチンではなくプロシージャを使用する
新しいコードを書くのであればサブ・ルーチンを使用するという選択肢はもはやありません。サブ・ルーチンを使用するとローカル変数やパラメータではなくグローバル変数を使用しなければならないという制限があり、プログラムの保守が困難になります。今の時代のコードではもっぱらサブ・プロシージャを使用します。
番号付きインジケータではなく名前付きインジケータを使用する
プログラムでインジケータを使用することは全く問題はありません。どのプログラミング言語にもフラグやブール演算フィールドといった概念があり、RPGのプログラマはこれらをインジケータと呼んでいます。ただし、インジケータを含めプログラム中のすべての変数には、その変数が何を意味するのかを容易に理解できるような意味の名前を付けておく必要があります。あなたが書いたコードを私が読んでいてErrorOccurredという名前の変数があったら、エラーが起きたら*ONにセットされ、それ以外のときは*OFFにセットされるというのがすぐにわかります。しかし*IN74という名前の変数を見てもそれが何を意味するのかさっぱりわかりません。もちろん調べることは可能ですが、それでは時間がかかってしまい生産的ではありません。プログラムは保守がしやすいように、理解しやすいようにしてください。組み込み関数(BIF:Built In Function)を使用して可能な限りインジケータを置き換えてください。そして置き換えが可能でない場合は、番号つきインジケータではなく名前付きインジケータを使用してください。今のRPGでは番号付きインジケータを使用しなければならない理由はありません。
正しいデータ構造を使用する
プログラム中で変数を見たらその名前からその変数がデータ構造の一部かどうかが明白になっていなければなりません。プログラムを読んでいて変数を見て「いったいこの変数にはいつ値がセットされるのだろう」と考えさせられ、結局その直前の行でデータ構造が変わっていたとわかったことが何度となくあります。レガシーのRPGプログラムでは、通常の変数とデータ構造の一部となっている変数とを見分けるのは困難でした。今のRPGでは、正しいデータ構造を使用して通常の変数とデータ構造の一部となっている変数がはっきりと分かるようにしておきましょう。
ファイル用の正しい構造を使用する
データ構造の場合と同様に、サブ・フィールドやファイルのフィールドも分かりやすいものでなければなりません。RPGではファイル中のフィールドに対して外部定義の正しいデータ構造を使用するという機能があります。私の場合はファイル名にちなんだ名前をデータ構造に付けています。たとえば、ファイル名がCUSTMASだったらそのファイルから読み込んだ値を格納するデータ構造にはCUSTMAS1という名前を付けます。メモリー中に1つ以上のレコードを同時に記憶する必要がある場合は、2つ目の変数にはCUSTMAS2という名前を付ける、といったようにします。データ構造は正しいものなので、私が書いたコードはそのフィールドをCUSTMAS1.Custno、CUSTMAS1.Name、CUSTMAS1.Address、CUSTMAS1.PhoneNoといったように参照します。こうした名前の付け方をすることで、それぞれのフィールドがどのファイルからのものであるのかが明白になり、異なるファイル間で名前が重複するのを避けることができます。V5R4でリリースされたEVAL-CORRというopcodeを使用すると、フィールド名が一致しているフィールドを異なるデータ構造の対応するフィールドに容易に移動することができます。
他の言語の特徴を利用する
RPGの最大の課題の1つはRPG用のフリーのツールやアド・インがないことです。たとえばExcelのスプレッドシートに書き出しをするルーチン、あるいはグラフやチャートを生成するルーチンのライブラリを作ることになったとしましょう。CやJavaではこうしたツールはたくさんありますが、RPG用のツールはほとんどありません。しかしそんなことであきらめてはいけません。他の言語で記述されたプログラムやプロシージャ、メソッドなどを呼び出せるRPGの機能を利用しましょう。RPGでは、正しいprototypeを作成するだけで、Javaや他のILE言語で書かれたルーチンを直接呼び出すことができます。こうすれば、RPG言語の利点を犠牲にすることなく、サード・パーティ製のツール(そのほとんどがフリーのもの)を利用することができます。
可能であればSQLを使用し、OPNQRYFは決して
使用しない データベースとやり取りをするときには、RPGのネイティブ・レコードI/O関数を使用したほうが良い場合があります。特にファイルがトランザクション・ファイルで、その中で1度に1レコードずつ処理するような場合です。しかし、集合ベースの処理を使用したルーチンを記述する場合は、SQLを使用してください。組み込みSQLプロセッサにより、RPGのopcodeと同じようにSQL文をRPGのコード中に組み込むことができます。SQLはその機能のパワーと豊富さにより、特定の基準に一致したレコード集合を選択するのに最適なツールとなっています。今のアプリケーションでは決してOPNQRYFを使用しないでください。OPNQRYFは明らかに過去のレガシーとなっています。SQLの方がより強力ですし、(使い方を習得してしまえば)使いやすく、OPNQRYFよりもずっと高速です。
緑色の画面はもう使用しない
RPGは緑色の画面用のプログラミングをするためだけにあるものだという神話をこれ以上続けさせないでください。5250端末は1970年代のテクノロジーです。80年代初期のMS-DOSのプログラムでさえもっと進んだものでした。次の段階へ進む時が来たのです。今のRPGの画面がどのようなものかの例を図1に示します。同様に、印刷イメージの例を図2に示します。今のアプリケーションでは、社外に公開されているアプリケーションだけでなく、そのアプリケーションが同じ事業所のSystem
iを利用している社員用の社内アプリケーションでさえ、5250のインタフェースがウェブ・インタフェースで置き換えられています。ウェブ・インタフェースでは「シン・クライアント」機能が提供されており、すべてのプログラム・ロジック(ビジネス・ロジックも表示ロジックも)が同じサーバー上で稼働していて、今までのクライアント/サーバー型のプログラムによる「シン・クライアント」ソリューションと比較して、その導入、配布、保守が大幅に簡素化されています。CGIDEV2は、RPGのプログラマがピュアなRPG環境でウェブのインタフェースが使用できるようにするための簡単な方法を提供しています。ビジネス・ロジックと表示ロジックを分離してあれば、RPGをJava、.NET、PHPと組み合わせて使用して豊富なウェブのフロント・エンドを構築することが可能です。
今後のルール
IBMのとある優秀な知人によれば、RPGは今後も当面の間は開発および機能強化が続くとのことです。つまり、時が経てばもっとモダンな機能が使えるようになるということです。しかしこれは80年代や90年代と同様の方法でプログラムを書き続けることができるということではありません。コンピュータ・テクノロジは進化を続けていますのであなたのプログラムも進化をさせていかなければなりません。
すべてを一度に進化させる必要はありませんが、新しいテクニックを自分のプログラムに少しずつ取り入れてください。プログラムに新しいテクニックが入り、ユーザー・インタフェースがよくなるだけでなく、保守も容易になり、柔軟性が高まっていけば、ユーザーもRPGのとりこになることでしょう。