Am I implementing OOP correctly here?

As I’m trying to learn metatables and the proper usage of self, I decided to create my first script that uses some OOP elements. Because of this, I’d like to know if I implemented it properly, or if I’m not using efficiently. Below you may find my localscript code.

local metaTable = {}
metaTable.__index = metaTable

local function setup(character)
	local self = setmetatable({}, metaTable)
	self.Trove = Trove.new
	local humanoid = character:WaitForChild("Humanoid")

	self.Trove:Connect(character.ChildAdded, (function(child: Instance)
		if child:IsA("Tool") and child.Name == "Tray" then
			prompt.Enabled = true; print("equipped")
		end
	end))

	self.Trove:Connect(character.ChildRemoved, (function(child: Instance)
		if child:IsA("Tool") and child.Name == "Tray" then
			prompt.Enabled = false; print("unequipped")
		end
	end))
end



if player.Character then
	setup(player.Character)
end

player.CharacterAdded:Connect(setup)

Any feedback is most appreciated!

I’m also using Trove to avoid a memory leak, so this is why you’ll see it be used.

Instead of a local function, do this:

function metaTable.Setup()

I would also use PascalCase for the metaTable(so turn it to MetaTable)

I also probably would rename it to MetaTable.new() and not Setup

Also, at the end of the function, add a return self

im questioning what your purpose for using metatables is in this code example, since your “self” table isn’t really inheriting from any properties or functions from “metaTable”.

are there any more functions/methods in metaTable than what you’ve shown in the code?
because so far if you were to replace this line with

local function setup(character)
	local self = {}

absolutely nothing would change