Moduli:table/getUnprotectedMetatable
< Moduli:table
Jump to navigation
Jump to search
Versioni i datës 10 gusht 2025 08:45 nga Kujdestari7 (diskuto | kontribute) (Krijoi faqen me "local _getmetatable = debug.getmetatable -- For testing (and just in case it gets enabled). if _getmetatable ~= nil then -- Avoid debug.getmetatable() throwing an error if 0 arguments are passed, -- for parity with the other function. return function(t) return _getmetatable(t) end end _getmetatable = getmetatable local pcall = pcall local rawget = rawget local setmetatable = setmetatable local type = type --[==[ Attempts to retrieve the input value's metatable, a...")
Udhëzuesi për këtë modul mund të krijohet te Moduli:table/getUnprotectedMetatable/doc.
local _getmetatable = debug.getmetatable
-- For testing (and just in case it gets enabled).
if _getmetatable ~= nil then
-- Avoid debug.getmetatable() throwing an error if 0 arguments are passed,
-- for parity with the other function.
return function(t)
return _getmetatable(t)
end
end
_getmetatable = getmetatable
local pcall = pcall
local rawget = rawget
local setmetatable = setmetatable
local type = type
--[==[
Attempts to retrieve the input value's metatable, and returns it if found. If the value does not have a metatable, returns {nil}. If the input value does have a metatable, but that metatable is not possible to retrieve because it is protected with the `__metatable` metamethod, returns {false}.
This is a useful way to ensure that functions can reliably distinguish between objects that do not have metamethods, objects with known metamethods, and objects with unknown metamethods.]==]
return function(t)
local mt = _getmetatable(t)
-- If `mt` is nil, there's no metatable.
if mt == nil then
return nil
-- If `mt` is not a table, the real metatable is protected and there's no
-- way of retrieving it.
elseif type(mt) ~= "table" then
return false
end
-- Try setting `mt` as the metatable with `setmetatable`; if the metatable
-- is protected, this will cause an error to be thrown (revealing it as
-- protected), and if it isn't, then `mt` must be the real metatable anyway,
-- so nothing has changed. Also make a special exception for data loaded via
-- mw.loadData(), which sets each metatable at its own __metatable key as a
-- way to stop the use of setmetatable() without actually hiding it. This is
-- spoofable, but low-risk.
return (pcall(setmetatable, t, mt) or rawget(mt, "mw_loadData") == true) and mt or false
end