Home > front end >  Making variables available inside environment with load function in Lua
Making variables available inside environment with load function in Lua

Time:03-22

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

  • Related