Passed parameter changes from Folder to

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

When I pass a folder to a function I would like it to still be a folder inside the function. I’d like to get this code working.

  1. What is the issue? Include screenshots / videos if possible!

I am passing a Folder to a function in a module and when I breakpoint within the module the folder seems to be a table. The table contains 1 function, that’s all.

Some relevant code:

RollingClient:

local replicatedStorage = game:GetService("ReplicatedStorage")
local remotes = replicatedStorage:WaitForChild("Remotes")

local animationModule = require(script:WaitForChild("AnimationModule"))

local screenGUI = script.Parent
local animations = screenGUI:WaitForChild("Animations")
local rollButton = screenGUI:WaitForChild("RollButton")

local debounce = false
rollButton.MouseButton1Click:Connect(function()
	if debounce == false then
		debounce = true
		
		local rolledNumber = remotes.RollFunction:InvokeServer()
		animationModule:rollAnimation(animations, rolledNumber) -- PASS FOLDER
		
		task.wait(1)
		
		debounce = false
	end
end)

AnimationModule:

local tweenService = game:GetService("TweenService")

local info = TweenInfo.new(0.2, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)

local function animateText(text1, text2, rolledNumber)
	text1.Position = UDim2.fromScale(0.5, 0.35)
	text1.TextColor = rolledNumber[3]
	text1.Text = rolledNumber[1]
	text2.Text = "1 of " .. rolledNumber[2]
	
	tweenService:Create(text1, info, {Position = UDim2.fromScale(0.5, 0.5)}):Play()
	task.wait(0.2)
end

return {
	rollAnimation = function(animationFolder: Folder, rolledNumber)
		local background = animationFolder:WaitForChild("Background") -- HERE FOLDER LOOKS LIKE A TABLE
		local title = animationFolder:WaitForChild("Title")
		local rarity = title:WaitForChild("Rarity")
		
		background.Visible = true
		title.Visible = true
		
		for i, Table in ipairs(rolledNumber) do
			animateText(title, rarity, Table)
		end
		
		task.wait(1)
		
		background.Visible = false
		title.Visible = false
	end,
}

Error message: Players.MeMeMe.PlayerGui.MainScreenGui.RollingClient.AnimationModule:17: attempt to call missing method ‘WaitForChild’ of table - Client - AnimationModule:17

https://ibb.co/JHQtvs1

https://ibb.co/HBZdYv4

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried using “require” to get the AnimationModule. I was thinking that would solve it, but for some reason it just thinks that folder is a table. I breakpoint just before calling the method and the folder looks fine, after I call the function I put a breakpoint inside the function, see image - looks like a table containing a function.

First question, second post - please let me know how I can improve my question. I’ve only been Roblox dev-ing with Lua for a week so be gentle - I got 99% of this watching youtube. Thanks!

I HAD to post it here in order to find the solution.

Original code:

animationModule:rollAnimation(animations, rolledNumber)

Working code:

animationModule.rollAnimation(animations, rolledNumber)

I’m surprised it worked at all with the : colon - but changing the method call to a dot “.” solved the problem.

Do you understand why this is, or would you like an explanation?

I’m not 100% sure - an explanation would be great!

That’s because you are setting a function to a variable, that is:

rollAnimation = function()

and not making a function with the name “rollAnimation”.

function moduleName:rollAnimation()

A bit small difference but it exists. Setting a function to a variable is not the same as making a function with a name.

That is exactly the same code as OP had before.

local Module = {}

function Module.doSomething(...)
    -- ...
end

return Module

In the above code, the function is a one of Luau’s many syntax sugars.

function Module.doSomething(...)
    -- ...
end

Translates to

Module.doSomething = function(...)
    -- ...
end

Which results in a dictionary with the key “function” referencing a function. This dictionary is then exported from the module. This is equivalent to:

return {
    doSomething = function(...)
        -- ...
    end
}

The issue is that you are using colon notation to call the function.

There’s this “special” variable called self, and it’s automatically defined as the first parameter when you use colon notation to define a function.

local tbl = {}

function tbl:foo()
    --self is defined here implicitely
end

tbl:foo() --we used colon notation to call it; in the function, self references tbl

When you use it to call a function in a table, it will automatically pass the table itself as a parameter. This means the table is actually getting stored in animationFolder. To fix this, use a dot to call it or add a non-used parameter at the start.
animationModule.rollAnimation(animations, rolledNumber)

1 Like

You accidentally entered the territory of the implicit “self” parameter. This feature of Lua(u) was introduced to facilitate pseudo-OOP (Object-Oriented Programming). I won’t go into how the parameter is used, but I will explain how it operates:

An implicit parameter is parameter of a function that is not explicitly defined. A value is assigned to that parameter when the function is called, and the parameter is usable within the function’s scope. It’s like a localized built-in, a ghost variable.

When using the following syntax, Lua(u) will enable the implicit parameter:

local Module = {}

function Module:doSomething(...)
	print(self)
	print(...)
end

return Module

The key component of this syntax is the : in the function signature.

Now that the implicit “self” parameter is available, what value does it hold exactly? Well, let’s try calling the function to find out!

local Module = require(--[[Path.to.ModuleScript]])

Module:doSomething(1, 2, 3)

image

It looks like we got a populated table. Upon expanding this table, we find something interesting…

image

It seems like the value of self is Module, and this is the case. But notice how I called doSomething with that same colon operator? What happens if I use the dot operator?

image

It seems like self stole the first argument I gave to the function and assigned itself as that value. Once again, this is the case. So what’s really happening here?

Well, just as I spoke on syntax sugar in a previous reply, we see it once again. The following code is another form of syntax syntax sugar:

Module:doSomething(1, 2, 3)

Is being translated to

Module.doSomething(Module, 1, 2, 3)

This supports the behaviour of “self” seen in the first test call. When invoking a function of a table with the colon operator, the first argument passed to that function will always become that table. The original arguments now passed in afterwards.

In your case, your code was equivalent to:

function Module.doSomething(...)
    -- ...
end

This function signature does not notify Luau of the desire for the implicit “self” parameter, so calling this function with the colon operator would simply offset your arguments:

function Module.doSomething(self, ...)
    -- ...
end

This led to “animationFolder” becoming “self”, which is why you saw a table

1 Like