Class members becoming nil/disappearing in module

I’m having an issue with class member becoming nil and being unable to access them in member methods. The onEvent method use to be the print statement that’s been commented out and worked with no issues. The issue arises from trying to get the class member table eventQueue

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

Access a class member (table) self.eventQueue and insert/remove elements.

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

Attempting to index self.eventQueue in any way results in errors such as “Attempt to index nil value” or “attempt to get length of a nil value”.

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

Moving the Rijst.new function to the top. I even set a breakpoint before return self and it shows the empty table as it should.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Rijst module

local Rijst = {}
Rijst.__index = Rijst

function Rijst.new()
	local self = setmetatable({}, Rijst)
	self.eventQueue = {} -- this just magically disappears..?
	return self
end

function Rijst:createComponent(name)
	assert(name ~= "BaseComponent", "Cannot create a BaseComponent by itself!")
	local Object = script.Parent.Components:FindFirstChild(name)
	if not Object then return nil end
	Object = require(Object)
	if Object then
		return Object.new(self, nil)
	end
end

function Rijst:onEvent(object, eventName, ...)
	assert(#self.eventQueue <= 300, "Event queue has exceeded an absurd amount (300)")
	table.insert(self.eventQueue, { Object = object, EventName = eventName, Data = ... } )
	--print("Object '" .. object.rawObject:GetFullName() .. "'' received event '" .. eventName .. " with arguments(s) " .. tostring(...))
end

function Rijst:peekEvent()
	if #self.eventQueue > 0 then return self.eventQueue[1] end
	return nil
end

function Rijst:popEvent()
	if #self.eventQueue > 0 then 
		local e = self.eventQueue[1]
		table.remove(self.eventQueue, 1)
	end
	return nil
end

local ClassNames = {
	"Frame",
	"TextBox",
	"TextLabel",
	"ImageLabel",
	"ImageButton",
	"Button",
	"ScreenGui"
}

function isGuiObject(className)
	return ClassNames[className] ~= nil
end

function Rijst:createFromTree(object)
	assert(typeof(object) == "Instance", "Non-instance passed to Rijst:createFromTree")	
end

return Rijst

Here’s a function from a BaseComponent module class which is a super class for any gui objects.

function BaseComponent:registerEvents(events)
	assert(typeof(events) == 'table', "Invalid argument to registerEvents, expected table, got " .. typeof(events))
	for k, v in pairs(events) do
		self.rawObject[v]:Connect(function(...)
			self.rijstInstance:onEvent(self, v, ...)
		end)
	end
end
1 Like

Strangely enough, changing local self = setmetatable({}, Rijst) to setmetatable(Rijst, {}) fixed this for now and doesn’t mutate the table when it’s passed to another object. I don’t feel like it’s 100% correct though as the other threads on OOP I’ve seen on this forum do it the former way. If there’s ever a need to subclass this object I feel as if it’s going to wreak havoc.