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.

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top