尾端的 Nil 參數 |
|
在我看來,lua 標準函式庫應清除,不要使用傳遞的引數數量來決定如何運作。
strfind(s,exp)
應該導致與下列結果相同:strfind(s,exp,nil,nil)
然後,你可以透過使用最大引數數量為任何函數撰寫封裝器
function mystrfind(a,b,c,d) -- do some extra handling here... return strfind(a,b,c,d) end
範例(ReubenThomas 在 lua-l 論壇的信件)
t = {} tinsert(t, 3, "hello", 1) print(t[3])
hello
時,會得到 1
。
tinsert(t, n, gsub(...))
現在我重新閱讀時,我發現這與尾端的 nil 問題相反 - lua 函數會忽略額外的引數,而 c 函數會收到所有的引數(而且 tinsert 會將其最後一個參數插入) - 最好將此頁面標題定為「lua 函數和 c 函數在引數處理上有不同處理方式所造成的問題」 -- PeterPrade
然而,在後續討論中,當人們試圖修正 tinsert 的異常時,遇到了尾端的 nil 問題 - 他們最後必須發現你無法為 lua 中的 tinsert 撰寫適當的封裝器函數。讓我引用 ET 對該討論串的最後訊息
function tinsert(t, ...) if arg.n == 1 then %tinsert(t, arg[1]) elseif arg.n == 2 then %tinsert(t, arg[1], arg[2]) else error("wronger number of args ("..arg.n+1..") for tinsert"); end end
tinsert(t, foo())
--> 可能產生 tinsert(t,a,b)
tinsert(t, x, foo())
--> 可能產生 tinsert(t, x)
function readfrom(f) local h, err if f then h, err = %readfrom(f) else h, err = %readfrom() end ...
郵件列表中出現另一個範例
> I just noticed that contrary to what you might expect, if you > pass "nil" as the fourth argument of strfind, it does a plain match. > Looking at the source, str_find indeed simply looks to see whether it > has a fourth argument. Sigh, another example of the arg handling ad hockery... > This is rather annoying, as in some other cases where it's nice to be > able to pass "nil" instead of omitting the argument. You say it... > It would not be contrary to the 4.0 manual to change this behaviour >[...] > Could this be done? Sure, it _could_. One could fix this place by converting the test lua_gettop(L)>3 to luaL_opt_int(L,3,0)==1, or one could finally start thinking about cleaning up argument handling in the C-API... >[...] is there any way around this? function strfind(a,b,c,d) c = c or 1 -- c has a similar problem... if d then return %strfind(a,b,c,d) else return %strfind(a,b,c) end end
在這裡加入更多範例...