Capil ka isi

Modul:table/setParent

Matan Wiktionary

Dokumentasi untuk modul ini dapat dibuat di Modul:table/setParent/doc

-- Imported from enwiktionary
-- Source: https://en.wiktionary.org/wiki/Module:table/setParent
-- License: CC BY-SA

local table_get_unprotected_metatable = "Module:table/getUnprotectedMetatable"
local table_index_ipairs_module = "Module:table/indexIpairs"
local table_index_pairs_module = "Module:table/indexPairs"

local rawset = rawset
local require = require
local setmetatable = setmetatable

local function get_unprotected_metatable(...)
	get_unprotected_metatable = require(table_get_unprotected_metatable)
	return get_unprotected_metatable(...)
end

local index_ipairs
local function get_index_ipairs()
	index_ipairs, get_index_ipairs = require(table_index_ipairs_module), nil
	return index_ipairs
end

local index_pairs
local function get_index_pairs()
	index_pairs, get_index_pairs = require(table_index_pairs_module), nil
	return index_pairs
end

return function(t1, t2, setter)
	-- get_unprotected_metatable() returns nil if there's no metamethod or false
	-- if it's protected. A protected metatable will cause an error to be thrown
	-- once setmetatable() is called anyway, but this way avoids the problem of
	-- getmetatable() returning arbitrary values from a __metatable metamethod.
	local mt = get_unprotected_metatable(t1)
	-- Use rawset() if `t1` already has a metatable, as metamethods are accessed
	-- with rawget() when invoked.
	if mt then
		rawset(mt, "__index", t2)
		rawset(mt, "__ipairs", index_ipairs or get_index_ipairs())
		rawset(mt, "__pairs", index_pairs or get_index_pairs())
		if setter then
			rawset(mt, "__newindex", t2)
		end
	else
		mt = {
			__index = t2,
			__ipairs = index_ipairs or get_index_ipairs(),
			__pairs = index_pairs or get_index_pairs(),
		}
		if setter then
			mt.__newindex = t2
		end
	end
	setmetatable(t1, mt)
	return t1
end