2016-03-10 6 views
4

__index вызывается при обращении в неизменном:Метаметода при доступе ключа, как изменяемый

local foo = bar["foo"]; 

__newindex вызываются, когда доступ изменяемого индекса, который не существует:

local bar = { } 
bar["foo"] = 123 -- calls __newindex 
bar["foo"] = 456 -- does NOT call __newindex 

Есть метаметод, который можно вызвать при доступе к ключу как изменяемое время evey, т. е. не только, если ключ еще не существует?

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

+0

__index и __newindex только огонь, если ключ не имеет значения, связанного с ним. – warspyking

ответ

3

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

+0

Спасибо. Я забыл упомянуть, что мне не нужно, чтобы значения, которые пользователь помещает в таблицу, действительно присутствуют в таблице. Эти значения будут храниться в собственном коде, поэтому наличие пустой таблицы - это то, что мне нужно, потому что она будет запускать __newindex каждый раз и не будет дублировать данные как в коде C, так и в Lua. Я пойду далеко. – Virus721

1

Я уверен, что таких метаметодов вы не просите. Но вы можете попробовать сделать обходной путь, чтобы получить то, что вы хотите.

Например, вы можете попробовать использовать __call метаметод таким образом:

local mt = {} 
function mt.__call(tbl, key, val) 
    -- this is called every time you use bar(key, val) 
    tbl[key] = val 
end 

local bar = setmetatable({}, mt) 

bar("foo", 123) 
bar("foo", 456) 

print(bar.foo) 

Или вы можете использовать функцию каким-либо другим способом для достижения этой цели.

+0

Спасибо. Хотя я хочу сохранить синтаксис подстроки, поэтому я просто буду делать то, что предлагает lhf, и держать таблицу пустой, и это то, что мне нужно в любом случае. – Virus721

0

Неизменяемость в Lua отсутствует, вы просто имеете в виду индексированный доступ и назначение. Lua 5.3 ...

Это событие происходит, когда таблица не является таблицей или не является ключом , присутствующим в таблице.

... для обоих случаев.

Ваш лучший вариант - хранить значения в другой таблице или подтаблице.

+0

Спасибо за помощь. – Virus721

+0

Lua 5.1 не отличается от Lua 5.3 в отношении метаметодов '__index' и' __newindex'. –

+0

@EgorSkriptunoff Спасибо за этот намек, я обновлю свой ответ. – Youka