I want to show same examples to help you figure out this confusion.
The primitive assignment example:
local test = {}
test['x'] = 1 -- equal to rawset(test, 'x', 1)
print(test['x']) -- 1
print(rawget(test,'x')) -- 1
the primitive assignment code test['x'] = 1
equal to rawset(test, 'x', 1)
when the table test
have no __newindex
metamethod.
then the __newindex
metamethod example:
local test = {}
setmetatable(test, {__newindex = function(t,key,value) end})
test['x'] = 1
print(test['x']) -- nil
print(rawget(test,'x')) -- nil
the assignment test['x'] = 1
will trigger to call the __newindex
function.
if __newindex
do nothing, then nothing happens, we will get nil result of test['x']
.
If the __newindex
function call rawset
:
local test = {}
setmetatable(test, {
__newindex = function(t,key,value)
rawset(t,key,value) -- t:test key:'x' value:1
end})
test['x'] = 1
print(test['x']) -- 1
print(rawget(test,'x')) -- 1
the code have same effect as the first example.
So the manual say:
"Lua does not perform the primitive assignment. (If necessary, the metamethod itself can call rawset to do the assignment.)"
Then the problem is, how we can use __newindex
?
It can be used to separate the old and new index in table.
local test = {y = 1}
local newtest = {}
setmetatable(test, {
__newindex =
function(t,key,value)
newtest[key] = value
end,
__index = newtest
})
test["x"] = 1
print(test['x']) -- 1
print(test['y']) -- 1
print(rawget(test, 'x')) -- nil
print(rawget(test, 'y')) -- 1
the old index 'x' and 'y' can all be accessed by test[key]
, and can be separated by rawget(test, key)