I've got a structure like this:
context = {
pi = math.pi,
sin = math.sin,
cos = math.cos,
tan = math.tan,
print = print
}
modules = {
m1 = {
variables = { x = 1 },
update = function(self)
local _ENV = self.variables
x = 2
m2.x = 2
end
},
m2 = {
variables = { x = 1 },
update = function(self)
local _ENV = self.variables
end
}
}
setmetatable(modules.m1, {__index = modules.m1.variables})
setmetatable(modules.m1.variables, {__index = context})
setmetatable(modules.m2, {__index = modules.m2.variables})
setmetatable(modules.m2.variables, {__index = context})
setmetatable(context, {__index = modules})
The idea is that users enter code into a UI and that code is pasted into the update
functions of the different modules, just after where local _ENV
is set. This user-entered code should be sandboxed. It should be able to access a few functions (the ones in the context
table) and the contents of other modules. Code in m1:update
should be able to refer to variables in m1.variables
without qualifying them; variables in other modules (ie ones in m2.variables
) should be accessible by qualifying them with the module name (ie m2.x
).
But the result I get is this:
$ lua -i test.lua
> = modules.m1.x
1
> = modules.m1.variables.x
1
> = modules.m2.x
1
> = modules.m2.variables.x
1
> = modules.m1:update()
> = modules.m1.x
2
> = modules.m1.variables.x
2
> = modules.m2.x
2
> = modules.m2.variables.x
1
Why is modules.m2.variables.x
not getting updated? And if, as it seems, modules.m2.x
is different to modules.m2.variables.x
, then where is modules.m2.x
coming from?
modules.m2.variables.x
is not getting updated because you only set __index
metamethod (which is used when retrieving a non-existing key), but not __newindex
metamethod (which is used when assigning a value to a non-existent key), and as the result the value is stored in modules.m2.x
table and not modules.m2.variables.x
table as you intended.
If I add __newindex
as in setmetatable(modules.m2, {__index = modules.m2.variables, __newindex = modules.m2.variables})
, I get the expected result.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.