Instead of returning an object in my module:New() function I return a proxy table that internally indexes and writes to the object. The issue is that in my module:Delete() method i set self._destroyed = true.
Luau thinks that I am trying to write to the proxy table and not the object table behind it.
I’ve tried to use self()._destroyed = true to use the metamethod __call but that doesn’t work either.
--!strict
local HttpService = game:GetService("HttpService")
local Style = require(script.Parent.Parent:WaitForChild("Style"))
local BaseStyle = Style:New()
type Data = {
ID: string,
Size: UDim2,
Position: UDim2,
AnchorPoint: Vector2,
Animated: boolean,
Instance: GuiObject,
Style: Style.Object,
_destroyed: boolean
}
export type Params = {
Size: UDim2?,
Position: UDim2?,
AnchorPoint: Vector2?,
Animated: boolean?,
Style: Style.Object?
}
local module = {}
module.__index = module
type PrivateObject = typeof(setmetatable({} :: Data , module))
type ProxyData = {
__call: (() -> PrivateObject),
__index: PrivateObject,
__newindex: (_: any, key: string, value: any?) -> nil
}
export type Object = typeof(setmetatable({}, {} :: ProxyData))
function module:New(instance: GuiObject, parent: GuiObject?, params: Params?): Object
local object = setmetatable({
ID = HttpService:GenerateGUID(false),
Size = UDim2.new(1, 0, 1, 0),
Position = UDim2.new(0, 0, 0, 0),
AnchorPoint = Vector2.new(0, 0),
Animated = true,
Instance = instance,
Style = BaseStyle,
_destroyed = false
}, module) :: PrivateObject
for key, value in pairs (params or {}) do
object[key] = value
end
local proxy = setmetatable({}, {
__call = function()
return object
end,
__index = object,
__newindex = function(_, key: string, value: any?)
if key == "Size" then
instance.Size = value :: UDim2
elseif key == "Position" then
instance.Position = value :: UDim2
elseif key == "AnchorPoint" then
instance.AnchorPoint = value :: Vector2
elseif key == "Instance" and object.Instance ~= nil then
error("Cannot set Instance")
elseif key == "ID" and object.ID ~= nil then
error("Cannot set ID")
end
object[key] = value
end
})
return proxy
end
function module.Destroy(self: Object)
if self._destroyed then return end
if self.Instance.Parent then
self.Instance:Destroy()
return
end
--self()._destroyed = true
self._destroyed = true
end
return module