Есть ли способ прослушивать изменения в таблице Lua?

Это чисто интересный вопрос.

Есть ли способ прослушивать / контролировать таблицу Lua и видеть, внесены ли в нее изменения, а затем вызывать функцию, когда в указанную таблицу добавляется новая запись?

Другими словами,

local t = {}

local function listener()
    print( "new entry added" )
end

t.text = "Hello!"

Есть ли какие-то методы, функции или другие средства, которые я могу использовать для вызова определенной функции, как только что-то было добавлено в таблицу.

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

Это выполнимо?


person James T.    schedule 21.08.2019    source источник


Ответы (2)


В Программе на Lua есть раздел, посвященный этой проблеме.

Программирование на Lua: 13.4.4 - Отслеживание доступа к таблице

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

В приведенной выше ссылке есть отличный пример, вот один для кода в вашем вопросе:

local function listener(k,v)
  print( "new entry added: \n\tKey = " .. k .. "\n\tValue = " .. v)
end
local metaTable

do
  local protectedTable = {}
  metaTable = {
    __index = function (t,k)
      return protectedTable[k]
    end,
    __newindex = function (t,k,v)
      protectedTable[k] = v   -- update original table
      listener(k,v)
    end
  }
end

local t = setmetatable({},metaTable)

t.text = "Hello!"
print(t.text)

Следует иметь в виду, что этот метод не позволит вам использовать pairs в t, поскольку это пустая таблица, и я не определял __pairs в метатаблице в моем примере.

person Nifim    schedule 21.08.2019

Да, есть способ отслеживать изменения.
В частности, используйте метатаблица.

__newindex - это метафункция, которая вам нужна, если вас интересуют только новые записи, а не измененные.

Если вы также хотите получать уведомления об изменениях, вам также понадобятся __index, __pairs, так как вы не должны сохранять записи в самой таблице.

person Deduplicator    schedule 21.08.2019
comment
Стоит отметить, что __index не помогает определить, было ли изменено поле. __index вызывается только в том случае, если индексированное значение отсутствует в таблице. lua.org/pil/13.4.1.html - person Nifim; 21.08.2019
comment
@Nifim Может быть, я недостаточно разбирался в том, зачем __index и __pairs. Разработано. - person Deduplicator; 22.08.2019