This question has some reference to the question Defining logical operator implies in lua. The following code works fine.
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
However the following code doesn't work.
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
It gives the error that attempt to perform arithmetic on a nil value (global 'imp'). This is probably because imp
is not available in names environment. Or is there any other reason? How imp
can be made available inside environment names?
CodePudding user response:
You hand names as the environment to the load function. The elements in names thus server as the global environment of the chunk you load. And that does not contain imp. To make it work, define names as follows: local names = { imp = imp }.
Then it will work.
CodePudding user response:
Another option is to use local names = {}; setmetatable(names, {__index = _G})
to allow access to global variables (variables directly in the names
table will "shadow" global variables though).
When replacing names
, you will have to set the metatable again. Alternatively, don't replace the "names" environment, but rather just update the i
and j
fields instead: names.i = i; names.j = j