Skip to content

[lua] Capture module-level varargs into _G.arg for Sys.args()#12602

Open
jdonaldson wants to merge 1 commit intoHaxeFoundation:developmentfrom
jdonaldson:lua-global-varargs
Open

[lua] Capture module-level varargs into _G.arg for Sys.args()#12602
jdonaldson wants to merge 1 commit intoHaxeFoundation:developmentfrom
jdonaldson:lua-global-varargs

Conversation

@jdonaldson
Copy link
Member

Summary

  • Fixes [lua] Global Var Args #10753
  • Environments like ComputerCraft pass script arguments via module-level ... (varargs) rather than populating _G.arg. The generated Lua wraps everything in functions, so ... becomes inaccessible and Sys.args() returns an empty array.
  • Adds a single line at the top of generated output: if _G.arg == nil then _G.arg = {...} end
  • Standard Lua already populates _G.arg, so the nil check makes this a no-op in normal environments.

Test plan

  • make haxe builds successfully
  • All 11,553 Lua unit tests pass
  • Verified Sys.args() works with standard lua script.lua arg1 arg2
  • Verified Sys.args() works in ComputerCraft-like invocation (loadfile + call with args, no _G.arg)

Environments like ComputerCraft pass script arguments via module-level
varargs (...) rather than populating _G.arg. Add a one-liner at the top
of generated output to capture ... into _G.arg when it is not already
set, making Sys.args() work in these environments.

Closes HaxeFoundation#10753
@tobil4sk
Copy link
Member

Sys.args() documentation states:

Returns all the arguments that were passed in the command line.

If Sys.args() can now contain values passed using loadfile instead of via the cli, then it is deviating from the specified behaviour.

Also, just because loadfile was used to load the current module, doesn't mean that _G.arg is necessarily nil. The current patch still gives no way to access {...} if _G.arg is not nil.

Expand for sample lua code where this can occur
-- wrapper.lua
local main = loadfile("main.lua")
main("load", "file", "args")
-- main.lua
print("_G.arg = " .. table.concat(_G.arg, " "))
print("{...} = " .. table.concat({...}, " "))
$ lua wrapper.lua real cli args
_G.arg = real cli args
{...} = load file args

I also think it's bad practice to overwrite a global value like _G.arg.

We should also avoid injecting more unconditionally included lua code. Even if it's one line now, it builds up gradually and one of the most common complaints about the lua target is the boilerplate required for simple programs. It is especially something to consider when only some users need it but it is added to everyone's code. Using define feature here to conditionally generate the extra line avoids this problem.

Maybe it's better to have a new method like lua.Lib.getModuleVarargs()? That avoids messing with the behaviour of Sys.args and gives full control to the user when _G.arg and {...} both exist but are different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[lua] Global Var Args

2 participants