Allowing user to create unlimited arguments?

If it is possible, how would I allow the user to create multiple arguments in a module without stating them? Some objects can do this, like RemoteEvents:

script.Parent:FireServer(... : ...any)

Is it possible I could do this with a module:

--module

function module:NewDropdown(DropdownSelection)
--script

module:NewDropdown("Option1", "Option2", "Option3")

I’ve already tried using ...any but it just gives me an error that it is an invalid type.

I believe that you can name a variable as local args = {...} and then utilize that, but I am not certain if this works (I saw this off of the Lua documentation). I will test this out and let you know.

Yep, it works. I tested the following code and it worked like a charm:

local function doSomethingWithVariables(...) 
	local args = {...}
	
	print(args)
end

doSomethingWithVariables(1, 5)
doSomethingWithVariables("a", 4, workspace)

Just follow a similar pattern and it should work fine for you.

2 Likes

For some reason the arguments don’t actually print, it gives some weird table code thing:

Also, why would I need the table? I tried this and it worked just fine:

local function doSomethingWithVariables(...) 
	print(...)
end

doSomethingWithVariables(1, 5)
task.wait(4)
doSomethingWithVariables("a", 4, workspace)

Yes, that is because that is how Lua works. If you want the arguments to print, you’ll have to loop through them and print them. You can do that by either individually printing each argument or converting it to a JSONEncoded string and printing it. I personally used the debugger for mine. The arguments are in the form of a table (or array), so you would have to use them like you’d use any other table or array.

(Example of using JSONEncode)

just check the studio output to not see the table, it only shows the table code when you look at console. Also, I have no idea why he’s saying to add it to a table AFTER sending it through the remote event, just have the client send them in a table.

local function doSomethingWithVariables(args) 
	print(args)
end

doSomethingWithVariables({1, 5})
doSomethingWithVariables({"a", 4, workspace})

Well I have a module that i’m editing and I want to make the UX good, so I will be using @Batimius’s method.

I understand why he’d want to do this. Imagine if the print function required you to write it as print({"a", variable, "b"}). That would be ugly and unnecessary. This achieves a clean code that works just like the one you posted.

1 Like

If the code worked for you, make sure to mark an answer as the solution so future people searching for this problem can find it easily. If you have any other questions, please let us know.

1 Like

In fact I do have one more question:

Why not just use this code rather than using a table? It achieves the same thing, if iterate over a table, then they just print separately.

local function doSomethingWithVariables(...) 
	print(...)
end

doSomethingWithVariables(1, 5)
task.wait(4)
doSomethingWithVariables("a", 4, workspace)

You can use this too of course, but the one I posted is for using the arguments themselves. If your whole goal is to just print the variables, then you can use that, but if you plan on manipulating them and accessing them individually, then you’ll need to add them to a table and use them that way. (For instance, you cannot do ...[1], but you can do args[1])

2 Likes

I thought I’d add another detail. The three dot notation, similar to ‘args’ in python and other OOP languages just allows it so that the function can take any number of parameters, each of which is condensed into a tuple. In lua tuples don’t really exist so it becomes a table. The utility of this is that you can make dynamic functions that aren’t constricted by preset parameters. The function could take no parameters at all and still work.

2 Likes

In this case, mine isn’t requiring a print({"a", variable, "b"}), I can’t even see where you got that one from. mine is just like yours but requires fewer lines as the client already passes it in the form of a table. I’m confused about where you got that this would be ugly and unnecessary? I quite literally provided a print line inside of the function that doesn’t make use of printing the table directly but through the variable. Try to read the code properly before dissing it.

Maybe you are not the one understanding. He is using it for a module. The print was an example. If your custom module function was called print, then you’d need to use it like that. Let me explain it in a different way. Say you have a class named OutputModule and you had a function called print that would take all arguments and print them in a special console in-game. In your example, if you wanted to utilize this function, you’d need to run OutputModule:print({"a", variable, "b"}). That is what I meant. Meanwhile, in my example, you can use OutputModule:print("a", variable, "b"). This is much more cleaner and understandable. Also, the “fewer lines of code” is literally a single line of code, and technically speaking, you don’t require that extra line of code if you are not planning on accessing individual arguments. What I said goes with any function. Say you have a function that adds a bunch of numbers together. What looks better, AddNumbers(5, 3, 1, 4), or AddNumbers({5, 3, 1, 4}). They both perform the same task and work in the same way, it is just that one requires an extra line of code when addressing individual arguments. This syntax allows for a much cleaner look and is used when you need to pass multiple arguments. @PerilousPanther provided a very great explanation about it above your reply. Please read and understand the reply before jumping to conclusions.

You could pack the arguments using table.pack which makes arguments into a table.

1 Like