Как я могу расширить свой метаметод __index, чтобы он работал независимо от уровня вложенности? Мой нынешний подход работает только для data.raw.a1.a2, но не для data.raw.b1.b2.b3 и подписчиков.
data = {
raw = {}
}
setmetatable(data.raw, { __index = function(t,k)
t[k] = {}
return t[k]
end })
data.raw.a1.a2 = { foo = "bar" }
data.raw.b1.b2.b3 = { foo = "bar" } -- throws an error
data.raw.c1.c2.c3.c4 = { foo = "bar" } -- throws an error
Я попробовал добавить второй setmetatable, но это работает только для еще одного уровня вложенности.
data = {
raw = {}
}
setmetatable(data.raw, { __index = function(t,k)
t[k] = {}
-- below is new
setmetatable(t[k], { __index = function(t,k)
t[k] = {}
return t[k]
end })
-- above is new
return t[k]
end })
data.raw.a1.a2 = { foo = "bar" }
data.raw.b1.b2.b3 = { foo = "bar" } -- now this works
data.raw.c1.c2.c3.c4 = { foo = "bar" } -- this still throws an error
Я не знаю, как сделать это рекурсивным, чтобы оно работало на всех уровнях вложенности. Отправьте помощь.





Используйте функцию-конструктор для создания таблиц с метатаблицей, которая имеет метаметод __index, который рекурсивно вызывает функцию-конструктор для создания новой глубины таблицы, когда индексированный ключ отсутствует.
Вот сокращенный пример, но его можно написать для повторного использования метатаблицы.
local function nestable(t)
return setmetatable(t or {}, {
__index = function (self, key)
local new = nestable {}
rawset(self, key, new)
return new
end
})
end
local data = nestable {}
data.raw.a1.a2 = { foo = 'bar' }
print(data.raw.a1.a2.foo)
Результат:
bar
Возможный дубликат stackoverflow.com/questions/36489928/…