OOP Printing "nil" for self

I want to set a variable in my object-oriented framework

When I print (self.Animator), it prints “nil” and every other variable I set.

--// Framework Stuff
local Framework = {}
local FrameworkMT = {__index = Framework}

--// Constructors
function Framework.new(Player)
	local self = {}
	
	
	self.Character = Player.Character
	self.Animator = self.Character:WaitForChild("Humanoid").Animator
	
	return setmetatable(self, FrameworkMT)
end

function Framework:Equip(WeaponName:string)
	if Disabled then return end
	
	--//
	print(self.Animator)
end

image

Does anyone know why this happens?

Either that object doesn’t exist in the humanoid, or your calling the function without taking self. So basically, when you call a function without it taking self, it won’t recognize it exists until you declare the argument first.

Im not,

Framework:Equip(LoadoutsPlugin.Standard.Primary)

Change that to:

local newFramework = {}
	
	
	newFramework.Character = Player.Character
	newFramework.Animator = newFramework.Character:WaitForChild("Humanoid").Animator
	
	return setmetatable(newFramework, FrameworkMT)

You don’t have to call it self in the .new function, that might be messing it up.

2 Likes

well when i print it in the .new(), it prints it but not in any other of the functions

Are you sure that you have the same issue with this small part of your code too?

1 Like

You pass Framework as self, not the object itself. The framework does not have the key Animator.

1 Like

Make sure that when you call :Equip() you’re calling it from the object returned from Framework.new() and not calling it from the required Framework ModuleScript itself.

4 Likes

He did create the animator. If you look at the way he calls Equip you’ll notice that the wrong object is passed as self. He needs to call the function from the object he created.

2 Likes

Can you simply do print(self) and see what it prints?
There should be an option to display the entire table in output, if you don’t have that enabled already.
I’m fairly certain I know what’s going wrong, but I need a bit more information.

1 Like

I mean this is a weird class setup anyways, try this:

--// Framework Stuff
local Framework = {}
Framework.__index = Framework -- This is fine, and rather common OOP paradigm.

--// Constructors
function Framework.new(Player)
	local self = setmetatable({
		_child = true, -- // This is a child (instanced) object.
	}, Framework)
	
	self.Character = Player.Character
	self.Animator = self.Character:WaitForChild("Humanoid").Animator
	
	return self
end

function Framework:Equip(WeaponName:string)
	-- // And just in case...
	if self and not self._child then error("Cannot call :Equip(WeaponName: string) on the Base Framework object! Use Framework.new(Player) to get a new Object!", 2) end
	if Disabled then return end
	
	--//
	print(self.Animator)
end

return Framework

Edit: Added missing return statement…

1 Like

I ran this:

--// Framework Stuff
local Framework = {}
local FrameworkMT = {__index = Framework}

--// Constructors
function Framework.new(Player)
	local newFrameworkMT = {}


	newFrameworkMT.Character = Player.Character
	newFrameworkMT.Animator = newFrameworkMT.Character:WaitForChild("Humanoid").Animator

	return setmetatable(newFrameworkMT, FrameworkMT)
end

function Framework:Equip(WeaponName:string)
    if Disabled then return end
	--//
	print(self.Animator)
end

return Framework

and it works.

2 Likes

Try replacing the period in “.new()” to a colon. I heard self is nil in a colon function. Though I haven’t tested this out yet.

The constructor should not use colons because self should not be set yet because we haven’t made an object yet.

As long as the if Disabled then return end is removed. The problem is with the way he calls the function.

It’s the other way around.

I’m 101% sure that the problem is this:

1 Like

this is how I would write it

local module = {}
module.__index = module

module.New = function(player)
	local self = setmetatable({}, module)
	self.disabled = false
	self.player = player
	return self 
end

module.Equip = function(self, weaponName)
	if self.disabled == true then return end
	print(self.player.Character.Humanoid.Animator)
end

return module
2 Likes

This right here was the issue! Thank you everyone for helping though, I was calling :Equip inside of the module its self. Thank you!!

1 Like