In short, I’m trying to find a method which is fired when setmetatable is called on a table, provides the metatable which was attempted to be set, then enables you to return the desired metatable (similar to UpdateAsync):
local myTable = {}
local myMetatable = {__someMagicalMathod = function(originalMetatable, metatableWhichWasAttemptedToBeSet)
-- do stuff with metatableWhichWasAttemptedToBeSet
return originalMetatable -- use the returned metatable (in this case, keep the original)
end}
setmetatable(myTable, myMetatable)
local newMetatable = {__index = function() end}
setmetatable(myTable, newMetatable) -- triggers __someMagicalMathod
Looking at the metatables wiki, there appears to be no metamethods to achieve this.
Is the __metatable method what you’re looking for or am I wrong, the wiki says it errors when you call setmetatable upon a table.
I guess another thing you can do is, for example using the __call metamethod, when a function is called, set its metatable, have a variable outside saying wether a metatable has been set before or not, and each time __call is triggered, check if it was set before.
Or simply, have a wrapper function as @sircfenner suggested, that sets the metatable, and has the checking with that variable that I mentioned.
local set = false
local function setmetatable2(t, mt)
if not(set) hen
setmetatable(t, mt)
return t
else
--do the stuff you wanna do
else
You could try doing something like this, not sure how great it’d work in practice.
local env = getfenv();
local oldSMT = env.setmetatable;
env.setmetatable = function(t, mt)
local current = getmetatable(t);
if (current and current.__metaupdate ~= nil) then
local new = current.__metaupdate(current, mt);
if (new ~= nil) then
oldSMT(t, new);
return;
end
end
oldSMT(t, mt);
end
setfenv(1, env);