Глобальная переменная с именем type скрывает встроенную функцию type () в Lua - PullRequest
3 голосов
/ 03 февраля 2011

Программа на C ++, над которой я работаю, использует lua для конфигурации.Он устанавливает несколько функций lua, используя жестко запрограммированный скрипт:

luaL_loadbuffer(pmLuaState, headerscript, strlen(headerscript), "header script");

Затем загружает файл конфигурации lua (который вызывает ранее упомянутые функции):

luaL_loadfile(pmLuaState, filename)

К сожалению, конфигурация LuaВ файле используется глобальная переменная с именем type, поэтому попытка вызова встроенной функции type () из моего заголовка не удалась с ошибкой Lua:

attempt to call global 'type' (a string value)

Из-за ограничений моего сценария я не могуотредактируйте оскорбительный файл конфигурации.Мне интересно, есть ли способ объяснить состояние, в котором я хочу использовать встроенную функцию type ().

Я новичок в Lua, так что, если есть лучший способ загрузки в эти сценарии,я буду избегать этой проблемы глобального скрытия, я открыт для нее (но опять же, я не могу редактировать скрипт конфигурации).

Lua версия: 5.1.4

Ответы [ 2 ]

3 голосов
/ 04 февраля 2011

Как только глобальная переменная была изменена, значение не может быть восстановлено, то есть вы должны запретить сценарию устанавливать _G.type в первую очередь или сохранить значение заранее.Второе относительно тривиально

local type = type -- problem solved

или вы можете использовать среды для решения этой проблемы.Это довольно распространенный сценарий для запуска.

local loadedmodules = {}
import = function(filename)
    if (loadedmodules[filename]) then
        return loadedmodules[filename]
    end
    local env = {}
    local func = loadfile(filename);
    local envmeta = {
        __index = _G -- changed thanks to comments
    }
    setmetatable(env, envmeta) -- Allow the imported script to read only our globals
    setfenv(func, env) -- set func's _G to env
    func() -- Load the script
    return loadedmodules[filename] = env -- Set the result and return it.
end

Это будет эквивалент C ++ автоматической защиты заголовков и макросов, автоматически подпадающих под определяющий файл.

Как только вы определите этот сценарий изЛуа, ты можешь загрузить его из C ++ и вызвать его относительно тривиально.Я не рекомендую делать какую-либо обширную логику Lua из C ++, стековый API очень отвратителен.

3 голосов
/ 04 февраля 2011

Вам следует песочница конфигурационных файлов, чтобы они не влияли на глобальную среду всей программы.

Вызовите lua_setfenv() с пустой таблицей в качествесреда в чанке, возвращаемая luaL_load*().

Обновление: если конфигурационному файлу нужны данные из глобальной среды, предоставьте его с метатаблицами.

В Lua:

setfenv(chunk, setmetatable({__index = _G }))

(Прочтите руководство, чтобы понять, как написать его на C).

Обратите внимание, что этот метод песочницы слишком слаб для ненадежного кода,Например, config мог бы делать что-то вроде table.concat = myevilfunction.См. Вики-страницу, на которую вы ссылаетесь выше, чтобы узнать о подходах к песочнице (хотя в вашем случае это будет излишним).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...