UWSCで可変引数を扱う
UWSCで可変引数を扱う方法を考えてみた。
UWSCでは、パラメーターに初期値を与えて省略可にできる。
しかし、この方法で可変引数を実現すると、二つの欠点がある。
- 可変個数の最大値が決まってしまう(実用上は問題ないことが多い)
- 初期値を適切に設定するのが難しいケースがある(数を渡して解決もできる)
初期値を与える方式
PROCEDURE vprintf(p1=NULL, p2=NULL, p3=NULL, p4=NULL) // 略 FEND
NULLを取りえない関数であれば、これで問題ない
もしあらゆる値を取りうる関数ならば、数を渡す
PROCEDURE vprintf(n=0, p1=NULL, p2=NULL, p3=NULL, p4=NULL) // 略 FEND
この例では第一引数の分だけ、p?が有効という規約。
が、どうしても最大数は固定となってしまう。
最大数をも可変にしたい場合を考える。
最大数を可変にした方式
追記 2014/12/09
ScriptControlのRunメソッド呼び出しでは、引数15個まででした、、、。
ということで、やむなく最大数固定の修正版を書きました。
UWSCで可変引数を扱う(修正版) - じゅんじゅんのきまぐれ
ScriptControlのRunメソッドが可変引数であることを利用する。
VariableArguments.uws
OPTION EXPLICIT IFB GET_UWSC_NAME = "VariableArguments.uws" THEN DIM test = 56 vprintf(VA.SC.Run("args", "めっせーじ", test, 17, "b")) ENDIF PROCEDURE vprintf(args) PRINT args.length DIM i IF args.length THEN args.Set(0, "書き換えた") FOR i = 0 TO args.length - 1 PRINT "<#TAB>" + args.Get(i) NEXT FEND MODULE VA PUBLIC SC TEXTBLOCK _variable_arguments_function function args() { var ret = arguments ret.Set = function(i, val) { this[i] = val } ret.Get = function(i) { return this[i] } return ret } ENDTEXTBLOCK PROCEDURE VA SC = CreateOleObj("ScriptControl") SC.language = "JScript" SC.AddCode(_variable_arguments_function) FEND ENDMODULE
解説
可変引数の関数は、オブジェクトを一つ受け取る関数として定義する。
(例は、PROCEDURE vprintf(args))
引数の個数は、lengthプロパティ。値の取得・設定は、Get/Setメソッドを利用する。
可変引数の関数を呼び出す際は、VA.SC.Run("args", 「可変個の引数」)を渡す。
原理としては、JScriptの関数が全て可変引数であり、全引数はargumentsオブジェクトに入っていることを利用しています。
argumentsオブジェクトは、Arrayに似て非なるものなので、アクセッサを追加しています。
Arrayの機能を使って載せ替えるという手もあるけど、ま、いいでしょ。