LUA / CHAPTER 12
Intercepting writes and raw operations
AdvancedUnderstand when metatable hooks do and do not run.
By the end of this chapter
- Explain __newindex for absent keys
- Use rawget and rawset deliberately
- Build validation around a backing store
The idea
A table’s __newindex hook is consulted when assigning a key that is not already present in the table. It is not a universal observer for every assignment. Updating an existing ordinary field bypasses that hook. Raw operations intentionally bypass the relevant metatable behavior and are useful inside a hook when the implementation needs to access actual storage without recursion.
To validate every write through an interface, a proxy table can keep its public raw storage empty and delegate values to a separate backing table. Reads use __index and writes use __newindex, allowing checks before the backing store changes. This is an API convention rather than an absolute security boundary if callers can reach the backing data or use raw operations on the proxy.
local writes=0
local t=setmetatable({}, {__newindex=function(self,k,v)
writes=writes+1
rawset(self,k,v)
end})
t.x=1
t.x=2
print(writes)
print(t.x)1 2
Only the first assignment targets an absent raw key. After rawset creates x, the later ordinary update bypasses __newindex.
Try it yourself
Implement a proxy that rejects negative assigned counts while keeping its backing table private.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING