Re: __update metamethod — intercept writes to existing keys (patch for 5.5.0)
"'Martin Eden' via lua-l" <[email protected]>
| Newsgroups | gmane.comp.lang.lua.general |
|---|---|
| Message-ID | <[email protected]> |
On 2026-04-08 10:37, chen chen wrote:
> Hello,
>
> I've been thinking about the gap between `__newindex` (new keys only) and
> the need to intercept updates to existing keys. The proxy-table workaround
> works but has notable overhead. I put together a small patch (~95 lines)
> for Lua 5.5.0 to explore what a native solution might look like — I'd love
> to hear if this direction has been considered or if there are concerns I'm
> missing.
>
> The patch adds an `__update` metamethod that fires when assigning to an
> existing key (including deletion via nil), complementing `__newindex`.
> Same-value writes are skipped as a fast-path optimization.
>
> ```lua
> local t = setmetatable({}, {
> __update = function(t, k, v)
> rawset(t, k, v) -- or do validation, logging, etc.
> end
> })
> t.x = 1 -- fires (new key, no __newindex)
> t.x = 2 -- fires (existing key, different value)
> t.x = 2 -- no fire (same value, fast-path skip)
> t.x = nil -- fires (existing key, deletion)
> ```
>
> This eliminates the proxy-table pattern (`__newindex` + `__index` +
> `__pairs` on an empty table). Tables without `__update` have zero overhead
> — a single bit flag gates the fast path.
>
> Full proposal, implementation details, and benchmarks:
> https://github.com/Ne9roni/lua-update-metamethod
>
> Feedback welcome!
>
Hello Chen,
I like concise text of your proposal.
Conceptually __update encompasses __newindex. In other words
__newindex is custom case of __update.
I understand that in add-on proposal you can't redesign things.
But still want to highlight discrepancy between conception and
implementation. In implementation __newindex and __update are
separate.
So if for some imaginary table we have all-forbidding __update and
all-allowing __newindex we can always add new items but not change
them.
And yeah, I'm not happy with Lua table metamethods. (Still love you Lua!)
__index and ___newindex are called only for not-found key.
Why this non-existence criteria? Why not throw them away in 2026 and
add read and write wrappers for table slots? Like OnRead(), OnWrite()
(or __read, __write if you like underscores)?
Thirty years ago associative array with exception callbacks was novel
and practical. Is it now? Can some essential changes ever happen?
-- Martin
--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/lua-l/0a007a41-090b-4dd3-b417-b50061461e40%40disroot.org.