Peer-reviewed code snippets that anyone can edit
A wiki for useful code snippets
Lua table proxy

Lua has index and newindex metamethods, but not a setindex or changeindex. This way you don't know whether a key was already set and it's been changed.
This is a simple solution that proxies a table so that exploits __newindex to set values to a subject instead of the proxy itself.
This way when a key is set, it's always a "new index" in the proxy.

proxy={}                                                                        
function proxy.new (subject)                                                    
   p={subject=subject}                                                          
   setmetatable(p, proxy)                                                       
   return p                                                                     
end                                                                             
 
function proxy:__index(key)                                                     
   print ("get", key)                                                           
   return rawget(self, 'subject')[key]                                          
end                                                                             
 
function proxy:__newindex(key, val)                                             
   print ("set", key, val)                                                      
   subject = rawget (self, 'subject')                                           
   subject[key] = val                                                           
end

Example usage:

mytbl = {}
 
container = proxy.new(mytbl)                                                    
print(container.test)                                                           
container.test = 'mytest'                                                       
print(container.test)                                                           
container.test = 'newtest'                                                      
print(container.test)

Notice "set" is being printed twice whenever a key is set, that's right what we wanted.