-- $Id: vararg.lua,v 1.24 2015/06/01 16:38:36 roberto Exp $ print('testing vararg') function f(a, ...) local arg = {n = select('#', ...), ...} for i=1,arg.n do assert(a[i]==arg[i]) end return arg.n end function c12 (...) assert(arg == _G.arg) -- no local 'arg' local x = {...}; x.n = #x local res = (x.n==2 and x[1] == 1 and x[2] == 2) if res then res = 55 end return res, 2 end function vararg (...) return {n = select('#', ...), ...} end local call = function (f, args) return f(table.unpack(args, 1, args.n)) end assert(f() == 0) assert(f({1,2,3}, 1, 2, 3) == 3) assert(f({"alo", nil, 45, f, nil}, "alo", nil, 45, f, nil) == 5) assert(c12(1,2)==55) a,b = assert(call(c12, {1,2})) assert(a == 55 and b == 2) a = call(c12, {1,2;n=2}) assert(a == 55 and b == 2) a = call(c12, {1,2;n=1}) assert(not a) assert(c12(1,2,3) == false) local a = vararg(call(next, {_G,nil;n=2})) local b,c = next(_G) assert(a[1] == b and a[2] == c and a.n == 2) a = vararg(call(call, {c12, {1,2}})) assert(a.n == 2 and a[1] == 55 and a[2] == 2) a = call(print, {'+'}) assert(a == nil) local t = {1, 10} function t:f (...) local arg = {...}; return self[...]+#arg end assert(t:f(1,4) == 3 and t:f(2) == 11) print('+') lim = 20 local i, a = 1, {} while i <= lim do a[i] = i+0.3; i=i+1 end function f(a, b, c, d, ...) local more = {...} assert(a == 1.3 and more[1] == 5.3 and more[lim-4] == lim+0.3 and not more[lim-3]) end function g(a,b,c) assert(a == 1.3 and b == 2.3 and c == 3.3) end call(f, a) call(g, a) a = {} i = 1 while i <= lim do a[i] = i; i=i+1 end assert(call(math.max, a) == lim) print("+") -- new-style varargs function oneless (a, ...) return ... end function f (n, a, ...) local b assert(arg == _G.arg) -- no local 'arg' if n == 0 then local b, c, d = ... return a, b, c, d, oneless(oneless(oneless(...))) else n, b, a = n-1, ..., a assert(b == ...) return f(n, a, ...) end end a,b,c,d,e = assert(f(10,5,4,3,2,1)) assert(a==5 and b==4 and c==3 and d==2 and e==1) a,b,c,d,e = f(4) assert(a==nil and b==nil and c==nil and d==nil and e==nil) -- varargs for main chunks f = load[[ return {...} ]] x = f(2,3) assert(x[1] == 2 and x[2] == 3 and x[3] == nil) f = load[[ local x = {...} for i=1,select('#', ...) do assert(x[i] == select(i, ...)) end assert(x[select('#', ...)+1] == nil) return true ]] assert(f("a", "b", nil, {}, assert)) assert(f()) a = {select(3, table.unpack{10,20,30,40})} assert(#a == 2 and a[1] == 30 and a[2] == 40) a = {select(1)} assert(next(a) == nil) a = {select(-1, 3, 5, 7)} assert(a[1] == 7 and a[2] == nil) a = {select(-2, 3, 5, 7)} assert(a[1] == 5 and a[2] == 7 and a[3] == nil) pcall(select, 10000) pcall(select, -10000) -- bug in 5.2.2 function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p48, p49, p50, ...) local a1,a2,a3,a4,a5,a6,a7 local a8,a9,a10,a11,a12,a13,a14 end -- assertion fail here f() print('OK')