Lua Metamethod __newindex
The __newindex metamethod intercepts a write to a missing key. It runs only when the key has no value stored in the table itself.
A storage table receives a new write
A write to a new key goes to the storage table. Reading the original table still gives nil for that key.
local store = {}
local t = {}
setmetatable(t, {__newindex = store})
t.score = 10
print(store.score, t.score)A guard function can reject a bad write
A guard function stores a score only when it is zero or more. A negative score is ignored, and a later good score is stored.
local function guard(t, k, v)
if k == "score" and v >= 0 then
rawset(t, k, v)
end
end
local t = {}
setmetatable(t, {__newindex = guard})
t.score = -5
print(t.score)
t.score = 20
print(t.score)A stored key bypasses the intercept
A write to a stored count changes the table itself. A write to a new key goes to the log table instead.
local log = {}
local t = {count = 1}
setmetatable(t, {__newindex = function(t, k, v)
log[k] = v
end})
t.count = 99
t.extra = 7
print(t.count, log.count, log.extra)Example
local function guard(t, k, v)
if k == "volume" then
if v >= 0 and v <= 10 then
rawset(t, k, v)
end
else
rawset(t, k, v)
end
end
local s = {}
setmetatable(s, {__newindex = guard})
s.volume = 15
print(s.volume)
s.volume = 8
print(s.volume)
s.title = "Hi"
print(s.title)Key points
- Missing key: a key with no value stored in the table itself.
- Intercept: a __newindex field takes over the write instead of storing it in the table.
- Table form: a table stored as __newindex receives the write for a missing key.
- Function form: a function stored as __newindex is called with the table, the key, and the new value.
- Stored key: a write to a key already stored in the table bypasses __newindex completely.
In this example, a settings table starts empty. A volume of fifteen is outside the allowed range, so it is ignored. A volume of eight is inside the range, so it is stored, and a new title is stored as well.
Note
reading a redirected key still gives nil unless a matching fallback supplies it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A table has a storage table as its __newindex field. A write to a new key goes where?