Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

api - Meaning of "Lua does not perform the primitive assignment." in 2.4 (concerning __newindex)

from https://www.lua.org/manual/5.3/manual.html see section 2.4. Concerning the metamethod operation __newindex states the following quote:

__newindex: The indexing assignment table[key] = value. Like the index event, this event happens when table is not a table or when key is not present in table. The metamethod is looked up in table.

Like with indexing, the metamethod for this event can be either a function or a table. If it is a function, it is called with table, key, and value as arguments. If it is a table, Lua does an indexing assignment to this table with the same key and value. (This assignment is regular, not raw, and therefore can trigger another metamethod.)

Whenever there is a __newindex metamethod, Lua does not perform the primitive assignment. (If necessary, the metamethod itself can call rawset to do the assignment.)

of that I ask what the follow specifically intends to say

"Lua does not perform the primitive assignment. (If necessary, the metamethod itself can call rawset to do the assignment.)"

Does this mean that if the value is a number, which is a primitive, it will not be assigned to the provided table through the metamethod event and we have to use rawget or something? This is very confusing and contradictory to me.

question from:https://stackoverflow.com/questions/65947699/meaning-of-lua-does-not-perform-the-primitive-assignment-in-2-4-concerning

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 __newindexmetamethod.

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...