More metamethods
__newindex, __call and __len let you guard writes, call tables like functions and change #.
In this page:
More metamethods
__newindex runs when you assign to a key that is absent, which allows read-only tables or tracking. __call lets a table be called like a function, and __len changes the result of the # operator. rawset and rawget read and write a table while bypassing the metamethods.
Note:
Use rawset inside __newindex, otherwise the assignment triggers __newindex again forever.
Example: More metamethods
local log = {}
local t = setmetatable({}, {
__newindex = function(tbl, k, v)
log[#log + 1] = k
rawset(tbl, k, v)
end,
__call = function(self, a, b) return a + b end,
__len = function() return 42 end,
})
t.x = 1
t.x = 2
t.y = 3
print(table.concat(log, ","), t.x)
print(t(2, 3), #t)
local readonly = setmetatable({}, {
__newindex = function() error("read-only table", 2) end
})
local ok, msg = pcall(function() readonly.a = 1 end)
print(ok, msg:match("read%-only table"))
-- Output:
-- x,y 2
-- 5 42
-- false read-only table
Login to try C/C++/Java/PHP code in the editor
Common Mistakes
- Assigning inside __newindex without rawset and recursing forever
- Expecting __newindex to fire for keys that already exist
- Expecting __len to be used by ipairs
Chapter Summary
- __newindex intercepts new keys
- __call makes tables callable
- __len overrides #
- rawset avoids recursion
🔒
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: