Метатаблицы? - PullRequest
       4

Метатаблицы?

0 голосов
/ 23 августа 2011

Я пытаюсь создать функцию __index в моей таблице, которая может обрабатывать ВСЕ поля, которые она получает .. Что я хочу сделать, так это то, что если я вызову таблицу следующим образом

mytable.str1.str2.str3

Я должен иметь возможность вернуть таблицу

{"str1", "str2", "str3"}

Обратите внимание, что str1, str2, str3 не определены, они просто строки.Я не пытаюсь создать подтаблицы str1, str2, я просто хочу, чтобы __index видел все за пределами первого периода.

К сожалению, мне кажется, что __index захватывает только str1 и жалуется, что «попытка проиндексировать поле» str1'(нулевое значение) "

Кто-нибудь знает, как это можно сделать?

Ответы [ 3 ]

2 голосов
/ 26 августа 2011

Я не уверен, почему вы хотите это сделать, но вот как вы это делаете.Комментарии объясняют хитрость, но в основном вам нужна вторая метатаблица для обработки таблицы, которая возвращается из первого вызова метаметода __index.

Если это не ясно, дайте мне знать, и я могу объяснить более подробно.

-- This metatable appends the new key to itself, then returns itself
stringtablemeta = {}
function stringtablemeta.__index(self, key)
    table.insert(self, key)
    return self
end

-- In response to the question in the comments:
function stringtablemeta.__tostring(self)
    local str = ""
    for i, v in ipairs(self) do
        if i > 1 then str = str .. "-" end
        str = str .. v
    end
    return str
end

-- This metatable creates a new table, with stringmetatable as its metatable
mytablemeta = {}
function mytablemeta.__index(self, key)
    local temp = { key }
    setmetatable(temp, stringtablemeta)
    return temp
end

-- set mytable to have mymetatable as it's metatable. This makes it so when    
-- you index into it, it will call the mytablemeta.__index method.             
--
-- That will return a talb with a single string, the key that was passed
-- in. that table will have it's own metatable, the stringmetatable, which
-- will cause it to append keys that are called on it with its own __index
-- metamethod
mytable = {}
setmetatable(mytable, mytablemeta)

test = mytable.str1.str2.str3

for k, v in pairs(test) do
    print(k, v)
end
1 голос
/ 23 августа 2011

Как сказала Николь, вы не можете сделать это непосредственно в Lua. Однако, возвращая специально созданные таблицы, вы можете добиться результата, аналогичного тому, который вы хотите. Взгляните на AutomagicTables на Lua-users Wiki для вдохновения.

1 голос
/ 23 августа 2011

Не может. Не без метатаблицы на каждой из этих таблиц.

mytable - таблица. str1 является другой таблицей. Таким образом, вы можете сделать то же самое, выполнив это:

local temp = mytable.str1
temp.str2.str3

А что касается Луа, это эквивалентно. Следовательно, единственный способ узнать, что было сделано на каждом этапе, - это дать всем из них особую метабильность. То, как вы объединяете различные значения в таблицу, - это то, что вам придется исследовать самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...