Этот вопрос имеет некоторую ссылку на вопрос Определение логического оператора подразумевается в 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
доступным внутри имен окружений?
Вы передаете имена в качестве среды функции загрузки. Таким образом, элементы в именах серверов являются глобальной средой загружаемого вами чанка. И это не содержит имп. Чтобы это работало, определите имена следующим образом: локальные имена = {имп = имп}.
Тогда это сработает.
Другой вариант — использовать local names = {}; setmetatable(names, {__index = _G})
, чтобы разрешить доступ к глобальным переменным (хотя переменные непосредственно в таблице names
будут «затенять» глобальные переменные).
При замене names
вам придется снова установить метатаблицу. В качестве альтернативы, не заменяйте среду «имена», а вместо этого просто обновите поля i
и j
: names.i = i; names.j = j