c - Creating referenced table element -
i created more or less complex table in c. want create reference on lower level of tree. possible?
idea:
elem000 +--> elem010 +--> elem020 +--> elem120 | +--> **elem121** | +--> elem122 +--> elem030 +--> elem130 | +--> elem131 | +--> elem132 +--> **elem121**
the elem121 should visible 1 level above, i.e. reference
i added example of wanted to..
void pushl(lua_state *l, const char * str) { char s[255]; strcpy(s, "elem"); strcat(s, str); lua_pushstring(l, s); // key strcpy(s, "value"); strcat(s, str); lua_pushstring(l, s); // value lua_settable(l, -3); } void maketable( lua_state *l ) { lua_pushstring(l, "tbl0"); // name of sub-table lua_createtable(l, 0, 0); lua_checkstack(l, 3); { pushl(l, "000"); lua_pushstring(l, "tbl1"); lua_createtable(l, 0, 0); lua_checkstack(l, 3); { pushl(l, "010"); pushl(l, "020"); lua_pushstring(l, "tbl2"); lua_createtable(l, 0, 0); lua_checkstack(l, 3); { pushl(l, "120"); pushl(l, "121"); pushl(l, "122"); lua_settable(l, -3); } pushl(l, "030"); lua_pushstring(l, "tbl3"); lua_createtable(l, 0, 0); lua_checkstack(l, 3); { pushl(l, "130"); pushl(l, "131"); pushl(l, "132"); lua_settable(l, -3); } lua_settable(l, -3); } lua_pushstring(l, "elem121"); lua_pushstring(l, "should reference elem121"); lua_settable(l, -3); } lua_setglobal(l,"____mytable"); }
bottom line: in lua, field variables cannot referenced there ways of doing want.
here comparison between c data structures , lua data structures.
in c, either:
have copy of value in 2 places
you can create copies in lua, too.
or, have pointer in 1 place points other place.
in c, means you'd have access them differently, 1 pointer deference, other without.
in lua, have function in 1 place returns value in other place. means you'd have access them differently, 1 function call, other without.
the following equivalent read-only pointer:
local elem000 = { elem010 = "elem010 value", elem020 = { elem120 = "elem120 value", elem121 = "elem121 value", elem122 = "elem122 value" }, elem030 = { elem130 = "elem130 value", elem131 = "elem131 value", elem132 = "elem132 value" }, elem121 = function(self) return self.elem020.elem121 end } print(elem000.elem020.elem121) print(elem000:elem121()) elem000.elem020.elem121 = elem000.elem020.elem121 .. " updated" print(elem000.elem020.elem121) print(elem000:elem121())
if need writable pointer approach needed.
update
a simple way writable pointer add optional value parameter. commonly used in javascript apis javascript has advantage of undefined
data type. in lua, we'll have use nil
, means can't write nil
value.
elem121 = function(self, value) if (value ~= nil) self.elem020.elem121 = value end return self.elem020.elem121 end
for true read-write field access, use __index , __newindex metatmethods. requires field not have key in table. metamethods invoked when indexing non-existing field reading (__index) or writing (__newindex).
local elem000 = { elem010 = "elem010 value", elem020 = { elem120 = "elem120 value", elem121 = "elem121 value", -- captured initial value elem122 = "elem122 value"}, elem030 = { elem130 = "elem130 value", elem131 = "elem131 value", elem132 = "elem132 value" }, elem121 = nil -- ignored } setmetatable(elem000, { __index = function(base, key) if (key=="elem121") return base.elem020.elem121 else return nil end end, __newindex = function (base, key, value) if (key=="elem121") base.elem020.elem121 = value else rawset(base, key, value) end end }) setmetatable(elem000.elem020, { elem121 = elem000.elem020.elem121, --[[ backing storage field, initialized existing value]] __index = function(base, key) if (key=="elem121") return getmetatable(base).elem121 else return nil end end, __newindex = function (base, key, value) if (key=="elem121") getmetatable(base).elem121 = value else rawset(base, key, value) end end }) -- make sure metamethods invoked on these fields rawset(elem000, "elem121", nil) rawset(elem000.elem020, "elem121", nil)
usage:
print(elem000.elem020.elem121) print(elem000.elem121) elem000.elem020.elem121 = elem000.elem020.elem121 .. " updated" print(elem000.elem020.elem121) print(elem000.elem121) elem000.elem121 = elem000.elem121 .. " again" print(elem000.elem020.elem121) print(elem000.elem121)
there various places store backing field , different styles of coding metamethods. code perhaps concise. and, leave code in lua c api, if wish.
Comments
Post a Comment