Calling ':Destroy()' method in a child class doesn't do anything

Hi this is my first time creating game using OOP approach and i have stumble across this problem that i can’t find the solution in dev forum.

so lets say that i have a class called Object:

local Object = {}
Object.__index = Object


function Object.new(Name,Health)
	local NewObject = setmetatable(
		{
			Name = Name,
			Health = Health,
			Died = "create a signal using signal module"
			
		},Object)
	
	return NewObject
end

function Object:Destroy()
	setmetatable(self,nil)
	self = nil
	print(self) -- it print nil
end


return Object

and a child class called Tree:

local Object = require(script.Parent.Object)

local Tree = {}
Tree.__index = Tree
setmetatable(Tree,Object)

function Tree.new()
	local NewTree = setmetatable(Object.new("Tree",5),Tree)
	return NewTree
end

function Tree:OnDied()
	-- do some animation or something
	self:Destroy()
	print(self) -- doesn't print nil
end


return Tree

as i mentioned above when i called the method “:Destroy()” from that child class it doesn’t print nil, can anyone explain to me what’s happening here? or you can suggest me other approach.

1 Like

That’s because self is the Tree module not the Object module and you have set the self = nil on the Object module, so it wont replicate on the Tree module unless if you have done it on a local/server script like this:

local Tree = require(script.Tree)
local object = require(script.Object)

local newTree = object.new("Tree", 5)
newTree:Destroy()

Or you can just do something like this on the Tree module since what your doing is a module script to module script.

function Tree:OnDied()
	self = self:Destroy()
	print(self) -- should definitely return a nil because you are not returning anything.
end

I don’t know how I can explain it to you properly of why it’s not printing a nil on your code, all I am saying is that you already have set the metatable on the Tree.new() so it wont replicate everything on the table like setting the self:Destroy() of course its not gonna print nil.

alright so why is this:

local Tree = require(script.Tree)
local object = require(script.Object)

local newTree = object.new("Tree", 5)
newTree:Destroy()
print(newTree) -- print empty table instead of nil

to be more clear i want to delete unused metatable after the instance inside that metatable destroyed so it wouldn’t caused memory leaks. why i want it to be nil? because there is other module script called object manager that hold reference to objects.

You could try :Remove() instead of :Destroy()

If you really want to remove all the data on the module why not just do it on the same module:

function Tree:OnDied()
	for key, _ in self do
		self[key] = nil -- this will print {} after the for loop ends
	end
	self = nil -- or just set it to nil
end

Huh. Renaming the function won’t change anything.

That’s off topic, it does not matter what type of function name you use as long as you understand what the function does.

i just dont want to copy paste the same function to other module script such as: Log,Rock,Grass,etc.

Why not just do something like this:

local Object = require(script.Parent.Object)
local Tree = {}

function Tree.new()
	local self = Object.new("Tree", 5)
	
	function self:OnDied()
		self:Destroy()
	end
	
	return self
end

return Tree

Still works the same way

Their reply was irrelevant, this is regarding a custom Destroy() method for a custom class implementation.

1 Like