メニューボタン
IBMi海外記事2023.11.21

リニア メイン プログラムでのプロシージャー主導型RPG

Gregory Simmons 著

私がサブルーチンを書かなくなり、代わりにプロシージャーを書き始めたのは、もう何年も前のことになります。もっとも、それは単に「ピカピカの新しいもの」だったからというだけであり、サブルーチンではない方から実際的なメリットが得られることはありませんでした。しかし、言語も進化し、自分も進化したためか、私がすべてのプロジェクトにアプローチする際の手法が、プロシージャー主導型RPGと呼んでいる手法であることに気が付きました。

では、単純なRPGプログラムを見てみましょう。この小さなプログラムでは、数学の分野からフィボナッチ数列(Fibonacci sequence)(訳注:前の2つの数の合計を新たな値とする数列)をテーマに取り上げて、処理を行ってみようと思います。

1	**Free

2	Dcl-s i    Uns(3) Inz(3);
3	Dcl-s fib1 Uns(3) Inz(0);
4	Dcl-s fib2 Uns(3) Inz(1);
5	Dcl-s fib3 Uns(3) Inz;

6	Exsr Perform_Fibonacci_Sequence;

7	*InLr = *On;
8	Return;

9	Begsr Perform_Fibonacci_Sequence;

10	  Dsply ('Fibonacci Sequence:');

11	  For i = 3 to 10;
12	    fib3 = fib1 + fib2;
13	    fib1 = fib2;
14	    fib2 = fib3;
15	    Dsply ('' + %Char(fib1));
16	  Enddo;

17	Endsr;

1行目: **Free - この小さなデモ プログラムは、完全フリーRPGで書かれます。

2行目~5行目: サブルーチンで使用するグローバル変数。最初の2つの数列(0と1)には関心がないため、カウントを3に初期化します。

6行目: サブルーチンを実行します。

7行目~8行目: これは従来のサイクルRPGプログラムであるため、LRをオンにして戻ります。

9行目~17行目: このサブルーチンは、単純なDo Whileループを実行して、現行の数値を表示してから、数列の次の数値を計算します。

このプログラムをコンパイルして実行し、joblogを表示すると、以下の数列を確認できます。

では、同じプログラムですが、サイクルRPGプログラムからリニア メインRPGプログラムへ切り換えたバージョンを見てみましょう。

1	**FREE
2	Ctl-Opt Main(Perform_Fibonacci_Sequence);

3  Dcl-Proc Perform_Fibonacci_Sequence;

4 	Dcl-s i    Uns(10) Inz;
5	Dcl-s fib1 Uns(10) Inz(1);
6	Dcl-s fib2 Uns(10) Inz(1);
7	Dcl-s fib3 Uns(10) Inz;

8	dsply ('Fibonacci Sequence:');

9	For i = 3 to 10;
10	  fib3 = fib1 + fib2;
11	  fib1 = fib2;
12	  fib2 = fib3;
13	  Dsply ('' + %Char(fib1));
14	Endfor;

15	End-Proc Perform_Fibonacci_Sequence;

1行目: このプログラムは、引き続き、完全フリー フォーマットになります。

2行目: リニア メイン プログラムにするために、メイン プロシージャーを指定するMainキーワードで制御オプションを追加します。

3行目: すぐにプロシージャーに取り掛かってフィボナッチ数列を実行できます。

4行目~7行目: これらは、フィボナッチ ループで使用したのと同じ変数です。ここでは、それらをローカルに定義することを選んだ点に注目してください。変数が複数のプロシージャーによって使用されることが分かっている場合は、先頭を「gbl_」で始めて定義することもあります。しかし、たいていの場合、どちらのプロシージャーでもそれらの値を必要とするものの間で変数を渡すだけにする方がよいと思います。何千とまでは言わないものの何百ものグローバル変数がある古いRPGプログラムをデバッグしていた頃の精神的な傷跡が残っているのかもしれません。サブルーチンが必要に応じてそれらの値を変え、表示装置ファイルもそれらを使用し、それらの名前が適切に指定されておらず、そして、大量のgotoです。わあああっ、助けてくれ、と叫びたくなるような状況だったのです。

8行目~14行目: これは、フィボナッチ数列を計算/実際に処理する同じロジックです。

この小さなプログラムには、RPGコンパイラーはRPGサイクルを埋め込みません。*Inlrをオンにセットする必要がないことに注目してください。リニア メインRPGプログラムであるため、実際に変数を初期化し、ファイルをオープンし、データ域をロックしますが、*Inlrを使用してシャットダウンをトリガーしません。さらに、スタートアップ時にオープンされたリソースは、プログラム終了時に暗黙的にクローズされません。このプログラムでは、サイクルRPGプログラムからリニア メインRPGプログラムへ移行したことによるパフォーマンスの向上は、ごくわずかです。しかし、プログラムの複雑さが増すため、パフォーマンスの上で重要な役割を果たす場合もあります。

上述のプログラムのそれぞれのバージョンをバッチで実行し、待機させて、1番目のバージョンでサブルーチン内の呼び出しスタックを、次いで2番目のバージョンでプロシージャー内の呼び出しスタックを表示しました。違いに注目してください。

サブルーチンの1番目のプログラムでは、「Fibonacci」というプログラムを実行していることが分かるだけですが、2番目のプログラムでは、「Fibonacci3」というプログラムの中の「Perform_Fibonacci_Sequence」プロシージャーを実行しているということが分かります。バグを調べている場合は、そうしたピンポイントの正確さはとても重要です。

同僚の開発者も私も、アフリカの諺で言う「象1頭を丸ごと食べる」ような巨大なプログラムのデバックはもう行っていません。たいていは、1口食べるだけのための小さなプロシージャーをレビューしているだけです。皆さんのショップに、私たちのところにあるような包括的なロギング プログラムがある場合は、想定外の事態が起こっても常にロギングされているため、すぐにログを確認して、どのプログラム、サービス プログラム、またはプロシージャーに問題が生じたのか正確に把握することができます。この場合もやはり、注意する必要がある小さなプロシージャーまですぐにたどり着けます。

さて、私が数えたところでは、このプログラムをサイクルRPGプログラムからリニア メインRPGプログラムに移行したことで、コード行数も17行から14行へ減りました。では、さらに少ない行数にすることはできるでしょうか。やってみましょう。

1	**Free
2	Ctl-Opt Main(Perform_Fibonacci_Sequence);

3	Dcl-Proc Perform_Fibonacci_Sequence;

4	Dcl-s i   Uns(10);
5	Dcl-s fib Uns(10) Dim(10);

6	Dsply ('Fibonacci Sequence:');
7	fib(2) = 1;

8	For i = 3 to %Elem(fib);
9	  fib(i) = fib(i-1) + fib(i-2);
10	  Dsply ('' + %Char(fib(i)));
11	Endfor;

12	End-Proc Perform_Fibonacci_Sequence;

配列を使用することで、変数の数を4つから2つへ減らすことができます。そして、計算も単純になります。これによってコード行数は14行から12行に減ります。表示機能を省けば、行数を10行まで減らせるかもしれません。以上、ちょっとした面白い頭の訓練でした。

最近、私は物事の考え方を、開発者の考え方からプロジェクト マネージャーの考え方へと変える方法を学んでいます。ここが、プロシージャー主導型RPGが本当に大きな効果があると感じるところです。象1頭を食べるとしたらどうやって食べるでしょうか。やはり、1口ずつ食べて行くしかないでしょう。そんな折、私が管理するプロジェクトとして、大規模なプロジェクトが与えられました。このプロジェクトの手伝いに配属された開発者たちにタスクを割り振る際に、私はそれぞれのビジネス機能をある作業単位にまで分割するようにしています。では、各作業単位とは何でしょうか。ご推察のとおり、それは プロシージャーです。

そのプロシージャーは、プログラムの中にあるのかもしれませんし、サービス プログラムでエクスポートされるモジュールの中にあるのかもしれません。しかし、これらのプロシージャーには、それぞれ実行するべき特定のジョブがあります。そして、これらのプロシージャーの中には、1つのプロシージャーによって呼び出されるだけであるために、呼び出し側のプロシージャーの一部として吸収することができるものもありますが、あるタスクを実行して、「その処理を行うプロシージャーはすでにある」ことに気付く必要があるケースをすでに目にし始めています。このような状況、すなわち、車輪はすでに発明済みであることに気付くことは、時間を節約することに等しいことです。そして、CTO、CIO、およびITマネージャーにとっては、それは費用を節約することに等しいことになります。

あわせて読みたい記事

PAGE TOP