Flexible parameter list for functions

I want to be able to send parameters to functions in the normal way, like this

test(1,"bb",color(255,0,0),3) 

or like this, naming them in a table

test({a=1,b="bb",c=color(255,0,0),d=3}) 

and I want to be able to put the results either into a table of data, or into local variables in the function I called. And I’d like to trap errors if I can.

(The advantage of named parameters is where there are so many, that it gets confusing for users to remember what order to put them in. Also, I can list them in any order, and leave out the parameters I don’t need. This is really good when you are doing partial updating all the time, eg managing the items a player picks up in a game.

The downside with named parameters is that users have to remember to put them in a table, and they aren’t really needed where there are only one or two parameters).

So I wrote something that handles either, putting the results in a table or returning a list of parameters that your function can handle. It throws errors if you mis-spell a named parameter or provide too many parameters. The code below demonstrates.

(I’m sure one of you wizards will improve it).


function setup()
    tbl={} --table to hold data
    --these tests put the parameters into the tbl table
    test(1,"bb",color(255,0,0),3) --fill table with normal parameters
    test({a=1,b="bb",c=color(255,0,0),d=3}) --fill table with named parameters
    test({b="bbbbb",d=333}) --change a couple of named parameters
    --this test puts the parameters into local variables in the test2 function
    test2(1,"bb",color(255,0,0),3) --normal parameters, don't put them in a table
    --deliberately cause an error
    test({x="bbbbb",d=333}) --mis-type a parameter
end

function test(...)  --uses a table, tbl
    Params(tbl,{"a","b","c","d"},arg)
    print(tbl["a"],tbl["b"],tbl["c"],tbl["d"])
end

function test2(...) --assign parameters to local variables
    local a,b,c,d=Params(arg)
    print(a,b,c,d)
end

--read table of parameters into a list
function Params(tbl,list,params) 
    if params~=nil and type(params[1])=="table" then --was named table
        --match the named params with the list provided
        local www
        for n,v in pairs(params[1]) do
            found=false
            for i=1,#list do
               if n==list[i] then 
                    tbl[n]=v
                    found=true 
                    break 
                end 
            end 
            if found==false then
                error("Parameter '"..n.."' invalid in "..debug.getinfo(2,"n").name)
            end     
        end 
    elseif params~=nil then --was an unnamed list
        if #params>#list then error("Too many parameters in "..debug.getinfo(2,"n").name) end
        for i=1,#params do
            tbl[list[i]]=params[i]
        end 
    else return unpack(tbl)
    end
end             

function draw()
end