Oop Style Destroy Method

I’m trying to more or less create would generally be considered a weak reference with an OOP style setup. So that when I call the “Destroy” method on my object, it becomes nil.

Here are my two relevent code pieces:
1)A Module in ServerScriptStorage named “Man” (The main OOP code).

local man = {}
man.__index = man
man.__mandex = {}
man.__id = 0

function man.new()
    local m = {}
    setmetatable(m,man)
    m.new = function() print("Nah, it's an instance bruv.") end
    m.__mandex = nil
    m.__type = "Man"
    m.__id = #man.__mandex+1
    m.Name = "Man_"..tostring(m.__id)
    man.__mandex[m.__id] = m
    return man.__mandex[m.__id]
end

function man:Destroy()
    if(self.__id~=0) then
    	setmetatable(self,nil)
    	man.__mandex[self.__id] = nil
    	table.remove(man.__mandex,self.__id)
    	self = nil
    else
    	print("You cannot destroy THE One True Man!")
    end
end

return man

2)A regular Script in the ServerScriptService

local SSS = game:GetService("ServerScriptService")
local Man = require(SSS:WaitForChild("Man"))

local m1,m2,m3

m1 = Man.new()
m2 = Man.new()
m3 = Man.new()

print(m1.Name) --prints "Man_1"
print(m2.Name) --prints "Man_2"
print(m3.Name) --prints "Man_3"

m2:Destroy()

print(m1.Name) --prints "Man_1"
print(m2.Name) --prints "Man_2" BUT I WANT TO ERROR AND WARN ABOUT INDEXING A NIL
print(m3.Name) --prints "Man_3"

I want to be able to call m2:Destroy() and have the instance be removed as well as all refences but a reference is still being held somewhere, I assume m2 itself but calling m2:Destroy() and then m2=nil after feels redundant.

You’d need to use the __metatable metamethod.

setmetatable(self,{__metatable = error('Man is destroyed!'})

Example:

setmetatable(setmetatable({},{__metatable = error('Man is destroyed!')}))
--> setmetatable(setmetatable({},{__metatable = error('Man is destroyed!')})):1: Man is destroyed!
setmetatable({},{__metatable = error('Man is destroyed!')}).Parent = workspace
--> setmetatable({},{__metatable = error('Man is destroyed!')}).Parent = workspace:1: Man is destroyed!

I think I get it but one thing is that the rblxlua doc for metatables/metamethods mentions that __metatable must be a “non-function value” isn’t error() a function? So shouldn’t I not be able to do this?

Relevant Link:

error is a function but the value returned seems to cause the error. It does work though, it locks the metatable.