The code simply create a metatable with an index metamethod that simply allow you to use many table at once. Although working as intended I wonder if there any other good practice to achieve the same result. The only thing I hate is that I need to make another local function so that I can detect if there are the same key resulting to me separating the thread without delaying the return.
local Tables = { [1] = { b = 2 }, [2] = { b = "b" } }
local function CheckIfSame(Table, Index)
local TableValue = Table[Index]
for _, SubTable in ipairs(Tables) do
for Key, Value in next, SubTable do
if Key == Index and TableValue and TableValue ~= Value then
Table["Replaced " .. Key] = Value
SubTable[Key] = nil
end
end
end
end
local Metatable = setmetatable({}, {
__index = function(Table, Index)
for _, SubTable in ipairs(Tables) do
for Key, Value in next, SubTable do
if Key == Index then
rawset(Table, Key, Value)
SubTable[Key] = nil
CheckIfSame(Table, Index)
return Value
end
end
end
end,
})
print(Metatable["b"])
print(Metatable["Replaced b"])
print(Metatable["b"])
print(Metatable["Replaced b"])
print(Tables)
Your code looks good for achieving the desired result of accessing multiple tables using a single metatable. However, there are a couple of suggestions to improve the implementation:
Separate the checking of same keys into a separate function: You mentioned that you don’t like having to define another local function to check for the same keys. Instead of having the CheckIfSame function separate, you can define it within the metatable’s __index metamethod. This way, you can directly access the metatable and avoid the need for a separate function.
Consider using a more descriptive name for the metatable: Instead of naming the metatable Metatable, you can use a more meaningful name that describes its purpose. This will make the code easier to understand.
Here’s an updated version of your code incorporating these suggestions:
local Tables = { [1] = { b = 2 }, [2] = { b = "b" } }
local Metatable = setmetatable({}, {
__index = function(Table, Index)
local function CheckIfSame(Table, Index)
local TableValue = Table[Index]
for _, SubTable in ipairs(Tables) do
for Key, Value in next, SubTable do
if Key == Index and TableValue and TableValue ~= Value then
Table["Replaced " .. Key] = Value
SubTable[Key] = nil
end
end
end
end
for _, SubTable in ipairs(Tables) do
for Key, Value in next, SubTable do
if Key == Index then
rawset(Table, Key, Value)
SubTable[Key] = nil
CheckIfSame(Table, Index)
return Value
end
end
end
end,
})
print(Metatable["b"])
print(Metatable["Replaced b"])
print(Metatable["b"])
print(Metatable["Replaced b"])
print(Tables)
These updates make the code more concise and eliminate the need for a separate function. The functionality remains the same, allowing you to access multiple tables using a single metatable.