i/OS 6.1 を実行している iSeries には、CL プログラムがあり、これを少しクリーンアップしています。このプログラムには、次の形式のカット アンド ペースト コードが含まれています。
IF COND(&ENV='PRD') THEN(DO)
CALL JCHKSTS PARM(&RS '127.0.0.1' '6500')
/* more junk here */
ENDDO
IF COND(&ENV='TST') THEN(DO)
CALL JCHKSTS PARM(&RS '127.0.0.1' '16500')
/* more junk here, same as in the first block */
ENDDO
/* repeat for several more &ENV values */
当然のことながら、これを見たときに最初に考えたのは、そのポート番号を変数に移動して、コードの重複ブロックをすべて削除しようということで、最終的には次のようになりました。
DCL &ENVPORT *CHAR(6)
IF COND(&ENV='PRD') THEN(CHGVAR VAR(&ENVPORT) VALUE('6500'))
IF COND(&ENV='TST') THEN(CHGVAR VAR(&ENVPORT) VALUE('16500'))
CALL JCHKSTS PARM(&RS '127.0.0.1' &ENVPORT)
/* more junk here, but only one copy of it now. */
このコードを実行すると失敗します。JCHKSTS プログラムは、文字列として宣言され、文字列で初期化されているにもかかわらず、3 番目のパラメーター (内部で整数に変換されます) として文字列と &ENVPORT 変数を想定しているためです。値は、明らかに文字列として渡されていません。(JCHKSTS 内からパラメーターを確認すると、ポート値の MAXINT の値が表示されます。)
'6500'
値を からに変更するという安価な手段でこれを回避しましたが、'6500 '
そもそもなぜうまくいかなかったのかわかりません。IBM のドキュメントには次のように書かれています。
呼び出しが CL プログラムまたは ILE CL プロシージャーから行われる場合、プログラム変数を渡すことができます。この場合、受信プログラムは、呼び出し側の CL プログラムまたは ILE CL プロシージャーで定義された変数と一致するようにフィールドを宣言する必要があります。
そして、確かに、受信プログラムは文字列を期待しているように見えます。変数を6文字の文字列として宣言しました。動作するはずです。
それで、私は何かを逃しましたか?変数を実際の数値としてではなく、数値の文字列表現として受信側のプログラムが認識できるようにするには、どのように変数を宣言すればよいですか?