Gibt es eine Möglichkeit die Signatur einer Lua-Funktion zu bestimmen?
-
02-07-2019 - |
Frage
Vor kurzem Lee Baldwin zeigte, wie ein generic, variable Argument memoize Funktion . Ich dachte, es wäre besser, eine einfachere Funktion zurückzukehren, in dem nur ein Parameter erforderlich ist. Hier ist mein total gefälschter Versuch:
local function memoize(f)
local cache = {}
if select('#', ...) == 1 then
return function (x)
if cache[x] then
return cache[x]
else
local y = f(x)
cache[x] = y
return y
end
end
else
return function (...)
local al = varg_tostring(...)
if cache[al] then
return cache[al]
else
local y = f(...)
cache[al] = y
return y
end
end
end
end
Offensichtlich versagt select('#', ...)
in diesem Zusammenhang und würde nicht wirklich tun, was ich so wie man will. Gibt es einen Weg ins Innere zu sagen, memoize , wie viele Argumente f erwartet?
„Nein“ ist eine feine Antwort, wenn Sie sicher wissen. Es ist keine große Sache zu verwenden zwei separate memoize Funktionen.
Lösung
Ich denke, man in die Debug-Informationen gehen könnte und bestimmen die von dem Quelle-Code, aber es ist im Grunde ein „Nein“, sorry.
Andere Tipps
Ja, für Lua-Funktionen, aber nicht C-Funktionen. Es ist ein bisschen quälenden und ein wenig lückenhaft.
debug.getlocal
arbeitet an aufgerufenen Funktionen, so dass Sie die Funktion in Frage stellen haben. Es zeigt keine Spur von ...
es sei denn, der Anruf genug Parameter übergibt. Der folgende Code versucht, 20 Parameter.
debug.sethook
mit dem Ereignis „Anruf“ eine Gelegenheit gibt, die Funktion abzufangen, bevor es irgendeinen Code ausgeführt wird.
Dieser Algorithmus arbeitet mit Lua 5.2. Ältere Versionen wären ähnlich, aber nicht gleich:
assert(_VERSION=="Lua 5.2", "Must be compatible with Lua 5.2")
Ein kleiner Helfer Iterator (für Effizienz inlined werden könnte):
local function getlocals(l)
local i = 0
local direction = 1
return function ()
i = i + direction
local k,v = debug.getlocal(l,i)
if (direction == 1 and (k == nil or k.sub(k,1,1) == '(')) then
i = -1
direction = -1
k,v = debug.getlocal(l,i)
end
return k,v
end
end
Gibt die Signatur (aber könnte eine Parameteranzahl und usesVarargs zurückkehrt, statt):
local function dumpsig(f)
assert(type(f) == 'function',
"bad argument #1 to 'dumpsig' (function expected)")
local p = {}
pcall (function()
local oldhook
local hook = function(event, line)
for k,v in getlocals(3) do
if k == "(*vararg)" then
table.insert(p,"...")
break
end
table.insert(p,k) end
debug.sethook(oldhook)
error('aborting the call')
end
oldhook = debug.sethook(hook, "c")
-- To test for vararg must pass a least one vararg parameter
f(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
end)
return "function("..table.concat(p,",")..")"
end
Ich bin mir ziemlich sicher, dass in Lua nicht tun können.