Эчтәлеккә күчү

Модуль:table/getUnprotectedMetatable

Wiktionary проектыннан

Модуль: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