UWSCのスクリプトを選択実行する

公式掲示板に、UWSCスクリプトを、選択してCALLで実行できないか、というのがあった。
それについての回答と解説です。



まずは回答

stuncloudさんの方法(exec実行)がおすすめです。
DOSCMDを使っても良いでしょう。(関連付けを利用する手も)


ただ、以下のような方法もあります。

DIM path[2]
path[0] = "test00.uws"
path[1] = "test01.uws"
path[2] = "test02.uws"
SELECT SLCTBOX(SLCT_BTN OR SLCT_STR,0,"会社",path)
CASE path[0]
  CALL "test00.uws"
CASE path[1]
  CALL "test01.uws"
CASE path[2]
  CALL "test02.uws"
SELEND

解説

CALLは、スクリプト開始時に、そこにスクリプトを(名前空間別で)取り込むステートメントです。
CALLの場所にスクリプトが展開される、という認識でいればだいたいあってます。
SELECTステートメントで実行スクリプトを分ければOK、ということです。

回答、EVAL大好き

DIM path[2]
path[0] = "test00.uws"
path[1] = "test01.uws"
path[2] = "test02.uws"
tes = SLCTBOX(SLCT_BTN OR SLCT_STR,0,"会社",path)
EVAL("CALL " + tes)

PROCEDURE dummy()
FEND

CALL "test00.uws"
CALL "test01.uws"
CALL "test02.uws"

解説、EVAL大好き

SELECTのインデントが微妙な人向きです。
変なPROCEDUREが増えてますが、シンプルですね。


EVALは、既にCALL済のスクリプトであれば呼び出すことができます。


しかし、不用意な場所でCALLしてしまうと、実行されてしまう可能性があります。
これを防ぐために、UWSCのMainスクリプトはFunction/Procedure/Moduleの前しか実行されない、ということを利用して、dummy()のプロシージャを置いておくのです。

回答、dummyプロシージャ置きたくない

こんなこともできます。

DIM path[2]
path[0] = "test00"
path[1] = "test01"
path[2] = "test02"
tes = SLCTBOX(SLCT_BTN OR SLCT_STR,0,"会社",path)
EVAL(tes + "()")

PROCEDURE test00()
	CALL "test00.uws"
FEND
PROCEDURE test01()
	CALL "test01.uws"
FEND
PROCEDURE test02()
	CALL "test02.uws"
FEND

解説、dummyプロシージャを置きたくない

PROCEDUREで封じ込めてしまえば、dummyは不要ですね。
、、、あれ、これなら最初のSELECTの方がいいね。
までも、呼びたい場所が増えた場合に、関数名で呼べるのがメリットかな。


EVAL陣営でdummyプロシージャやPROCEDUREに封じ込めが必要になるのは、CALLしたいスクリプトの書き方の問題、という話もあります。
しろまささんが使っていて、私も採用しているのですが、メイン実行時にGET_UWSC_NAMEでスクリプト名を判定するようにすると、CALLしやすくなります。
UWSCでINIのセクション・キーの一覧を取得する - じゅんじゅんのきまぐれ
こんな感じ。
これだと、単体で実行できた上、CALLして利用するのも容易です。
そもそも、CALL前提のスクリプトなら、FUNCTIONやPROCEDURE/MODULEしか書かないのも手です。
までも、それは個人の趣味の問題ですね。


個人的には、CALLはC言語のincludeだと思っているので、ファイルの先頭に書きたいのです。