Предоставление доступа к переменным внутри среды с помощью функции загрузки в Lua

Этот вопрос имеет некоторую ссылку на вопрос Определение логического оператора подразумевается в lua. Следующий код работает нормально.

    local function _implies(a, b)
      if a == 1 and b == 0 then return 0 
        else return 1 end
    end
    
    local my_right = {
        __mul = function(self, b)
            return _implies(self.a, b)
        end
      }
      
      local _mt =  {
        __mul = function(a)
            return setmetatable({a=a}, my_right)
        end
    }
    
    local my_left = {}
    setmetatable(my_left,_mt)
    imp = my_left
    local names = {}
    
    
    for i = 0,1 do
       for j=0,1 do
         names.i=i;names.j=j
       print(i, j, names.i *imp* names.j)
      
       end
    end

Однако следующий код не работает.

str = "i *imp* j"

local function _implies(a, b)
  if a == 1 and b == 0 then return 0 
    else return 1 end
end

local my_right = {
    __mul = function(self, b)
        return _implies(self.a, b)
    end
  }
  
  local _mt =  {
    __mul = function(a)
        return setmetatable({a=a}, my_right)
    end
}

local my_left = {}
setmetatable(my_left,_mt)
imp = my_left
local names = {}

for i = 0,1 do
   for j=0,1 do
     names.i=i; names.j=j
   print(i, j,  load("return " .. str,nil,"t",names)())
  
   end
end

Выдает ошибку, что попытка выполнить арифметику с нулевым значением (глобальный 'imp'). Вероятно, это связано с тем, что imp недоступен в среде имен. Или есть какая-то другая причина? Как сделать imp доступным внутри имен окружений?

Что такое компоненты React? Введение в компоненты | Типы компонентов
Что такое компоненты React? Введение в компоненты | Типы компонентов
Компонент - это независимый, многократно используемый фрагмент кода, который делит пользовательский интерфейс на более мелкие части. Например, если мы...
1
0
37
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы передаете имена в качестве среды функции загрузки. Таким образом, элементы в именах серверов являются глобальной средой загружаемого вами чанка. И это не содержит имп. Чтобы это работало, определите имена следующим образом: локальные имена = {имп = имп}.

Тогда это сработает.

Другой вариант — использовать local names = {}; setmetatable(names, {__index = _G}), чтобы разрешить доступ к глобальным переменным (хотя переменные непосредственно в таблице names будут «затенять» глобальные переменные). При замене names вам придется снова установить метатаблицу. В качестве альтернативы, не заменяйте среду «имена», а вместо этого просто обновите поля i и j: names.i = i; names.j = j

Другие вопросы по теме