[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Metatable methods
- From: Александр Машин <alex.mashin@...>
- Date: Tue, 21 Dec 2021 19:48:07 +0700
21.12.2021 19:37, Spar пишет:
Make a dummy table with metatable and __pairs metamethod in it, make
that metamethod return value A, put value B in dummy table.
Now call pairs on it and read first value. If __pairs was invoked, you
get A, if not regular pairs will return B
Thank you, but that's what I meant by probing. This is my current solution:
--[[
Redefined pairs and ipairs.
--]]
--[[
Whether a metamethod exists.
@param string func Function that is supposed to invoke the metamethod.
@param ?string method Metamethod to check.
@return bool True, if the metamethod is supported.
--]]
local function metamethod_supported (func, method)
return not _G [func] (setmetatable ({ 0 }, { [method or '__' .. func] =
function (tbl) end }))
end
--[[
Emulate a metamethod, if it does not exist.
@param string func Function that is supposed to invoke the metamethod.
@param ?string method Metamethod to emulate.
@return function Function redefined to take metamethod into account.
--]]
local function emulate_metamethod (func, method)
if not metamethod_supported (func, method) then
local raw = _G [func]
return function (...)
local metatable = getmetatable (tbl)
local metamethod = metatable and metatable [method or '__' .. func]
-- Do not simplify to return ... and ... or ...:
if metamethod then
return metamethod (...)
else
return raw (...)
end
end
else
return _G [func]
end
end
local pairs, ipairs = emulate_metamethod 'pairs', emulate_metamethod
'ipairs'
Alexander Mashin