Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do I recreate a Destroy method?

Heres the idea I'm using modulescripts to create objects

I want to call the Destroy method to destroy that object; all its properties, tied Instances, references, and Objects that were required from the modulescript. I want to leave NO DATA BEHIND

I was thinking of doing something like:

	function stuff:Destroy()
		for i, v in pairs(getfenv()) do
			if v:IsA("Instance") then
				v:Destroy();
			else 
				v = nil
				i = nil
			end
		end
	end

but alas, the function does not produce the desired effect.

Please help me achieve complete destruction

2 comments

0

Try using :remove() instead.

0

Can I ask what that will accomplish?

1 answer

Most of the time you don't need to recreate a Destroy function - lua's garbage collection will take care of it: whenever something no longer has a reference to it, it will eventually get garbage collected (often within a few seconds). ex:

local t = {}
t = nil
--At this point, the table still (probably) exists in memory [I believe lua can garbage collect while your code runs - even if your code doesn't yield - so it's technically not a guarantee, but it's very probable)
wait(3)
--At this point, the table is likely garbage collected since nothing refers to it

This works regardless of what information is contained within t. In fact, lua can handle circular references, too:

local t1 = {}
local t2 = {t1}
t1[1] = t2
t1 = nil
t2 = nil
--As you can see, we've created two tables that refer to each other. As before, they're still in memory.
wait(3)
--Despite the two tables referencing each other, lua knows that nothing else refers to them, so it garbage collects both

However, memory leaks are still possible. The easiest one is this scenario:

  • You create a Part, let's call it P.
  • Another script listens to P's Changed event (I believe it will need to connect it to a function that uses P, or else this example won't work)
  • You destroy all references to P (but don't call P:Destroy())

P thus cannot be garbage collected, even though you don't need it anymore.

Thus, you will need a custom Destroy function for some of your classes. Here's what you do:

  1. Create a Destroy function in the class
  2. For each thing that class initializes, clean it up if needed:
    • Call :Destroy() on any created instances (and any custom classes that also have a :Destroy function)
    • Call :disconnect() on any custom events (or :Destroy() on BindableEvents/etc)
    • Release any custom resources that need to keep track of how many references there are to it (ex if you have an object that is distributed to multiple coroutines/scripts and needs to destroy itself only after all those scripts are done with it. In that case, you can't just call :Destroy(), since other scripts may be using it. Instead, you need to keep track of the number of references, and only when that number reaches 0 does the object call Destroy on itself).
  • You do not need to clean up basic values (numbers, tables, strings, Vector3s, etc).
  • If you have nothing to destroy, there's no need for a :Destroy() function, but you might want one for consistency

If the ModuleScript contains a table of values, you might want to create/call some sort of "ClearData" function that erases the table (ex in another one of your questions you had a Deck of cards. If that ModuleScript actually contained a list of Decks in existence, you might want to clear that list (in preparation for a new round/game) so that those decks can be garbage collected, allowing you to make new ones).

1 comment

0

Do you have any idea as to how I could iterate through every variable in a given function within the modulescript? I'm calling getfenv but I

This discussion is preserved as it was. New answers, comments, and votes are closed.