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...