Модуль:table/getUnprotectedMetatable
Күренеш
Модуль:table/getUnprotectedMetatable/doc битен төзеп бу модульнең документациясен шунда урнаштырырга була
local getmetatable = getmetatable
local pcall = pcall
local rawequal = rawequal
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 it doesn't throw an error, it's the real metatable.
if pcall(setmetatable, t, mt) then
return mt
end
-- If `mt.__metatable` is `mt`, then the metatable is protected but must be `mt` anyway, since `__metatable` causes `getmetatable` to return the value at that key in the metatable (e.g. `mw.loadData` does this).
local __metatable = rawget(mt, "__metatable")
return __metatable and rawequal(mt, __metatable) and mt or false
end