Why would variables not become nil if what they're set to is nil?

My issue with this is that for an example I can’t do
if Projectile ~= nil then and I’m forced to do if Projectile:FindFirstChild(“Hit”) then
Why does that really happen?

1 Like

probably because another part of your script is setting that variable to something else

1 Like

local Part = Instance.new(“Part”)

Part:Destroy()

print(Part)

run this, it’d print Part

1 Like

It’s because the variable still has a reference to the now destroyed part (which in short just parents it to nil, locks the parent property and disconnects all connections), you have to set the variable to nil yourself, it does not do that itself to any variables that held a part that is now destroyed

1 Like

But isn’t the reference useless to the scripter? Wouldn’t it be better if it changed to nil (automatically)?

1 Like

Assert Instance.Parent instead of the Instance itself. It takes some time before it becomes garbagecollected by the memory management.

Unless I’m mistaken: Just set variables the standard way of variable = nil. The reference becomes lost and then successfully garbagecollected.

Yea that’s a solution, but what I want to figure out in this post is why wouldn’t it turn nil automatically

1 Like

Sure it would be better if it was done automatically, but it’s a bit unneeded considering it’s just an extra line of code you’d need to do for variables taht contain destroyed parts to set their reference to nil

The reason it wouldn’t turn into nil automatically is because Roblox doesn’t have the functionality to it yet, the only thing being niled is the Parent property

1 Like

If you have studied how the memory works here, the reference keeps the object “alive” until the reference is lost. If the reference is still there and it was earlier destroyed, the memory won’t remove it completely until the reference is removed or under a certain time(not sure if that happens). If you don’t remove the reference, the reference ends up piling up memory leaks. Yikes.

1 Like

Think of it like this:

local Part = {
    Parent = workspace
}

function Part:Destroy()
    self.Parent = nil
end

If you call Part:Destroy(), ‘Part’ still exists, what you’ve done is set a property of that instance to nil, not the instance itself.

2 Likes

Basically, when you try to destroy a part, it will set it to nil, but it will take maybe half or 0.1 a second. So you will still be able to access the Part, but nothing will happen with it

Does that mean I have to set it to nil or it might cause problems?

That’s only in certain circumstances, sometimes you don’t need to and I doubt that this should be the center of focus for now. I think the Maid class structure actually demonstrates that detail well and was discussed in RDC 2020 about the powerful code structures.

The variable itself won’t turn nil automatically regardless of time

pretty sure it will. Here, run this code:

local Part = Instance.new(“Part”)

Part:Destroy()

wait(1)

print(Part)

I ran it with wait(10) lol, so yea

1 Like

If you’ve referenced such variable within a particular scope, such as a function, then once that function finishes executing the variable reference will be garbage collected. It depends on your use case.

2 Likes

Wait, try this:
local Part = Instance.new(“Part”)
Part.Parent = workspace
Part.Position = Vector3.new(12, 473, 58)
Part:Destroy()

wait(1)

print(Part.Position)

It prints the position in the output

1 Like

References to destroyed Instances are not set to nil automatically, it has to be done manually