Difficulties learning Varargs

Hello, devs. I’m learning Varargs, and I know the basics of it. If I’m not mistaken, it is an array/table of parameters/arguments, like a variable number of further arguments, that must stand as the last parameter index.

Then, for instance:

local function Additional_Parameters(...)
	for index, value in ipairs({...}) do
		print("Argument ".. index..": "..value) --Will print the position of the parameter iterated and the value of the parameter.
	end
end

print(Additional_Parameters("Banana", "Apple", "Watermelon"))

--"Argument 1: Banana"
--"Argument 2: Apple"
--"Argument 3: Watermelon"

Correct me if I’m wrong.

I’m doing a module script and need to do a function when an object is activated. Therefore, using Varargs becomes imperative for me, as I have multiple callbacks/functions that share alike parameters.

Finally, the main reason I’m doing this post is because I don’t know why you need to close the function differently, instead of parsing it with “)” or without.

Activated = function(button, callback, ...)	
		button.Activated:Connect(function(...)
			callback(...)
		end, ...) -- here
	end,

Stuff I know is:

The function receives the arguments button, callback, and the indefinite variable of parameters (…). Moreover, when the button is activated, it connects to a non-named function, which conveniently receives the previous variable of parameters. In turn, the function is the Callback argument (a function), receiving the extra arguments.

Now, why does the end close with a comma and a “…)” after it? Is it like saying that it can receive Varargs? Additionally, is the code above even correct? And if not, how can it be fixed? Thank you in advance.

I don’t know why that’s being autocompleted, but that wouldn’t be correct.


Varargs don’t really work this way as this is pretty ambiguous to the VM. You likely meant to create something like this:

Activated = function(button, callback, ...)
    local passedArgs = {...} -- keep the original passed varargs in a table to be used in another function scope
	button.Activated:Connect(function()
	    callback(table.unpack(passedArgs)) -- pass the original arguments here
        -- You do this because the anonymous function here can have its own set of varargs, and overlap with the original varargs (also internal interpreter/compiler reasons)
	end)
end,
4 Likes

Varargs (...) is a tuple of arguments. They are not an array or table by default and you’re instead creating one when you use curly braces inside that ipairs call. That conversion allows that for loop to work without selecting through each argument. RBXScriptSignal’s :Connect() method does not allow you to pass in arguments that are appended to the arguments used to call a signal handler. Some functions, like pcall or coroutine.resume do though and they indicate that in their documentation with a ...: Tuple parameter.

3 Likes

Thank you! It was, indeed, weird. Now, I understand how I can properly use Varargs. I thought storing it on a table was when iterating with a for loop, only. However, why do you actually need to store it on a table instead of just implementing it on the callback?

Regarding the end, I think it was meant to be something like that, maybe?

Activated = function(button, callback, ...)
    local passedArgs = {...} -- keep the original passed varargs in a table to be used in another function scope
	button.Activated:Connect(function()
	    callback(table.unpack(passedArgs)) -- pass the original arguments here
        -- You do this because the anonymous function here can have its own set of varargs, and overlap with the original varargs (also internal interpreter/compiler reasons)
	end, table.unpack(passedArgs))
end,

With that you mean I cannot pass out arguments to :Connect() that were previously apprehended to another function?

Does it include other RBXScriptSignal’s?

Now I understand why you need to include it on a table, so it can be passed as the arguments to the function

Last question. How to make that so the game can either receive or not the Varargs? With that, I mean like, a function that includes the first two (button and callback), but not the others?

Don’t pass any further arguments; the table will just be blank and the behavior of the function won’t change

1 Like

After some time working on it, I noticed it breaks when I change it to another “system”. I realized my second value of the tuple parameters was returning nil, and it was a tween. “attempt to index nil with ‘play’”.

Older version, that breaks:

local function Create_Arg_List(...)
	local max_index = select("#", ...) 
	return {index = max_index; arguments = {...}}
end

return {

--Callbacks
Event = function(event, button, callback, ...:any)
		local event_choosen = button[event] -- checa qual evento deve ser ativado (Activated, MouseEnter, MouseLeave, etc...)
		
		local args_list = Create_Arg_List(...) -- vai retornar o max index e os argumentos.
		local unpacked = table.unpack(args_list.arguments, 1, args_list.index) -- desempacotar argslist
		
    	event_choosen:Connect(function()
			callback(unpacked) -- passar os argumentos originais aqui, e chamar a função
		end)
	end,

Newer version, that works:

Event = function(event, button, callback, ...:any)
		local event_choosen = button[event] -- checa qual evento deve ser ativado (Activated, MouseEnter, MouseLeave, etc...)
		
		local args = {...}
		
    	event_choosen:Connect(function()
			callback(table.unpack(args)) -- passar os argumentos originais aqui, e chamar a função
		end)
	end,

In the old version, the table is being unpacked but you’re only assigning one variable to the result so only the first argument is taken. Your Create_Arg_List function is already a default function: table.pack, which stores the length in an “n” key instead. Just make sure to unpack the arguments directly when calling the callback instead of storing it in a variable.

1 Like

Oh!!! So I’m like unpacking the table that includes multiple values, but I’m assigning only one variable to it?

So it is like:

local function Varargs(...:any)
    --Compacted on the previous Create_Arg_List Function
    local unpacked = table.unpack(...) --"Banana", "Apple"
    --It will only return "Banana", because "Apple" is not assigned a variable.
end

Got it! Thank you so much. I’ll fix it, and then tell you if it worked.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.