Trailing Nil Parameters |
|
In my opinion, the lua standard libraries should be cleaned up to not use the number of arguments passed in determining how to behave.
strfind(s,exp)
should lead to the same result as:
strfind(s,exp,nil,nil)
then you can write a wrapper for any function by using the maximum number of arguments:
function mystrfind(a,b,c,d) -- do some extra handling here... return strfind(a,b,c,d) end
Example (a mail of ReubenThomas on the lua-l list):
t = {} tinsert(t, 3, "hello", 1) print(t[3])
1
when I expect hello
.
tinsert(t, n, gsub(...))
Now that i am reading this again, i realize that this is the opposite of the trailing nils problem - lua functions ignore extra arguments, while c functions get them all (and tinsert happens to insert its LAST parameter) - Perhaps it would be better to title this page "Problems arising from the different treatment of arguments to lua-functions and c-functions" -- PeterPrade
However, later in the thread, when people were trying to fix the oddity with tinsert, they encountered the trailing nils problem - they finally had to realize that you cannot write a proper wrapper function for tinsert in lua. Let me quote ETs last message to that thread:
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())
--> may generate to tinsert(t,a,b)
tinsert(t, x, foo())
--> may generate to tinsert(t, x)
function readfrom(f) local h, err if f then h, err = %readfrom(f) else h, err = %readfrom() end ...
another example appeared on the mailing list:
> 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
add more examples here...