It is sometimes convenient to write x() when x is a string, instead of explicitly assert(loadstring(x))() each time. How can such a process be automated?

    1 answer 1

    The simplest solution:

     local strtab = getmetatable(''); -- Операция с метатаблицей для всех строк local strcalls = setmetatable({}, {__mode = 'v'}); -- Кэшировать результаты loadstring в слабую таблицу if strtab == nil then return error("I can't set default table for strings, sorry.", 2) -- И такое бывает! end; strtab.__call = function(str, ...) -- в момент x() local func; if strcalls[str] ~= nil then -- Если функция есть в кэше... func = strcalls[str]; -- ...взять её оттуда... else -- ...иначе... func = assert(loadstring(str)); -- ...скомпилировать её... strcalls[str] = func -- ...записать компилированый вариант в кэш... end return func(...) -- ...и выполнить! end; strtab = nil return strcalls -- Для доступа в внутренней таблице, не обязательно ловить 

    The last line allows you to access the cache if necessary (usually, this is not necessary).

    Note: in the pcall() argument, you can now also write a string, which is quite convenient. For example:

     require 'strcall' print(pcall 'string.dump("a")') --> false [string "string.dump("a")"]:1: bad argument #1 to 'dump' (function expected, got string)