Переменная Lua, определяющая объем с setfenv

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

Проблема, с которой я сталкиваюсь, является этим dofile всегда, кажется, выполняется в реальной глобальной среде, таким образом, внешние файлы просто бросают все свои объявления в _G.

Вот является пример основным файлом с комментариями, указывающими на мое принятие желаемого за действительное.

function myFunc()
    print("In the sandbox:")
    print("Should be 1:", a)  -- falls back to _G for lookup
    a = 2  -- instantiating new global for sandbox
    print("Should be 2:", a)  -- from sandbox
    print("Should still be 1:", _G.a)  -- from host environment

    dofile("loading.lua")  -- here's where things go wrong

    print "\nBack in the sandbox:"
    print("Should be 3:", a)  -- changed by loadfile
    print("Should STILL be 1:", _G.a)  -- unchanged
end

a = 1
local newgt = {} -- new environment
setmetatable(newgt, {__index = _G})
setfenv(myFunc, newgt)
myFunc()

print("\nOutside of the sandbox:")
print("Should be 1: ", a)  -- in theory, has never changed

И файл это загружается (loading.lua:

print ("\nLoading file...")

print("Should be 2: ", a) -- coming from the sandbox environment
a = 3
print("Should be 3: ", a) -- made a change to the environment

И наконец вывод я вижу:

In the sandbox:
Should be 1: 1
Should be 2: 2
Should still be 1: 1

Loading file...
Should be 2:  1
Should be 3:  3

Back in the sandbox:
Should be 3: 2
Should STILL be 1: 3

Outside of the sandbox:
Should be 1:  3
5
задан SJML 23 June 2010 в 03:18
поделиться

1 ответ

Описанная вами проблема также обсуждается на этой странице Предложение по пространству имен Dofile. Решение, похоже, заключается в следующей замене dofile:

function myapp.import(name)
  local f,e = loadfile(name)
  if not f then error(e, 2) end
  setfenv(f, getfenv(2))
  return f()
end

См. также: Sand Boxes

10
ответ дан 13 December 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: