← Back to Lua Course | Chapter 6: OOP with Metatables | Lesson 7 of 7

More metamethods

__newindex, __call and __len let you guard writes, call tables like functions and change #.

In this page:

  1. More metamethods

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

lua
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
Common Mistakes
  1. Assigning inside __newindex without rawset and recursing forever
  2. Expecting __newindex to fire for keys that already exist
  3. 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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.