Lua: Interpreting undefined variable by its name

1.6k views Asked by At

I have a function foo that can get nil values under certain circumstances, i.e. foo(VarA) while VarA is undefined. This undefined VarA should get interpreted as "VarA" but I can't invoke foo("VarA") because VarA should act as an option param (different from normal string params).

mt = {__index = function(t, k) return k end}
setmetatable(_G, mt)

This would get the desired result but now every other undefined variable would return its name. Like abc -> "abc". Do you see any way to only have a metatable active in this specific case? I could switch metatables in my foo method but when I'm in the foo block, the passed param is already nil and its too late.

Appendix: I think the question was not specific enough. Schollii's answer to pass params as a table was good but does not work as intended:

foo({option1 = delete, option2 = push})

This should have the key information (option1 and option2) plus the information of the value (even though delete and push do not exist in global or local namespace). Schollii's approach would give me the key information but not the value information (like "delete" and "push"). I can't define delete and push beforehand because these new "key-words" should get defined by the function itself later on. Passing those new keywords as a string is no option.

2

There are 2 answers

2
Oliver On

All you need is to test for nil and set VarA's value to its name:

function yourFunc(VarA)
    VarA = VarA or "VarA" -- if VarA is nil, it becomes the string "VarA"
    ... use VarA ...
end

However, you say that VarA should act as an option parameter. I gather you mean that VarA is optional. OK, but Lua does not support named arguments in function calls so if you have

 function yourFunc(arg1, arg2, optArg1, optArg2)
     ...
 end

then in order to call yourFunc with optArg2=something, you have to set optArg1 to nil:

 yourFunc(1, 2, nil, 3)

In other words you can't do yourFunc(1,2,optArg2=3) which would be pretty neat. But you can get pretty close by having yourFunc accept a table instead of a list of parameters:

 function setOptionalArgs(tbl, defaults)
     for i,v in ipairs(defaults) do
         if tbl[v] == nil then
             tbl[v] = v
         end
     end
     for k,v in pairs(defaults) do
         if tbl[k] == nil then
             tbl[k] = v
         end
     end
 end

 function yourFunc(args)
     setOptionalArgs(args, {'arg1', arg2=2, 'arg3'})
     -- ... use args.arg1, args.arg2 etc ...
     print(args.arg1, args.arg2, args.arg3)
 end

 yourFunc {}

Now you can call

 yourFunc {arg1=1}

which will automatically have arg2="arg2". Note that to be clean you should modify setOptionalArgs so only non-array keys get inserted in second loop.

1
Tom Blodget On

It seems like you are developing a domain-specific language within Lua. If that is your intent and you are successful, great. Otherwise, it would be better to stick to more a typical Lua programming style.

Similar to other suggestions:

-- lets the caller decide on the scope of varA
-- and the default string
foo(varA or "varA")