هل هناك طريقة لتحديد توقيع وظيفة Lua؟
-
02-07-2019 - |
سؤال
حديثاً، لي بالدوين أظهر كيفية كتابة أ وظيفة حفظ الوسيطة العامة والمتغيرة.اعتقدت أنه سيكون من الأفضل إرجاع دالة أبسط تتطلب معلمة واحدة فقط.إليكم محاولتي الزائفة الكاملة:
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
بوضوح، select('#', ...)
يفشل في هذا السياق ولن أفعل ما أريده حقًا على أي حال.هل هناك أي طريقة لمعرفة الداخل حفظ كم عدد الحجج F تتوقع؟
"لا" هي إجابة جيدة إذا كنت تعرف ذلك بالتأكيد.ليس مشكلة كبيرة استخدام اثنين منفصلين حفظ المهام.
المحلول
أعتقد أنه يمكنك الدخول إلى معلومات التصحيح وتحديد ذلك من الكود المصدري، ولكن في الأساس "لا"، آسف.
نصائح أخرى
نعم، لوظائف Lua ولكن ليس لوظائف C.انها معذبة بعض الشيء وسطحية قليلا.
debug.getlocal
يعمل على وظائف تسمى لذا عليك استدعاء الوظيفة المعنية.ولا يظهر أي تلميح لذلك ...
ما لم تمر المكالمة بمعلمات كافية.الكود أدناه يحاول 20 معلمة.
debug.sethook
مع حدث "call" يعطي فرصة لاعتراض الوظيفة قبل تشغيل أي رمز.
تعمل هذه الخوارزمية مع Lua 5.2.الإصدارات الأقدم ستكون متشابهة ولكنها ليست هي نفسها:
assert(_VERSION=="Lua 5.2", "Must be compatible with Lua 5.2")
مكرر مساعد صغير (يمكن تضمينه لتحقيق الكفاءة):
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
إرجاع التوقيع (ولكن يمكن إرجاع عدد المعلمات واستخداماتVarargs بدلاً من ذلك):
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
أنا متأكد من أنك لا تستطيع أن تفعل ذلك في لوا.