Some questions with Metatables

1. What’s different point with tables, In article, It says “it is stranger than normal tables”, But there is no “How and What?”.
2. In another article,
It says

setmetatable can’t change table’s metatables. while the metatable who gave the table a metatable is nil. So I tried an experiment.

local x = {}
local metaTable = {"a"}     
local metaTable2 = {"b"}     
setmetatable(x, metaTable) 
print(getmetatable(x))
setmetatable(x, metaTable2) 
print(getmetatable(x))

Through output, It was changed from a to b.

1 Like

I think that’s referring to actually changing the table’s contents. setmetatable merely attaches a table to be the metatable for the specified table, it doesn’t manipulate the table’s contents.

You’ve greatly jumbled what was said in setmetatable’s API reference.

Let’s get this straight. setmetatable is the sole function used to assign metatables to normal tables. It follows two distinct rules:

  1. If the metatable being assigned is not in fact a table, but nil, this operation will remove the metatable currently assigned to the normal table.
local normal = {}
local meta = {}

setmetatable(normal, meta)
print(getmetatable(normal)) --> table: 0x000000000002f1a0

setmetatable(normal, nil)
print(getmetatable(normal)) --> nil
  1. After assigning a metatable to a normal table with the __metatable metamethod set, setmetatable will be henceforth overriden, and additional calls to setmetatable on the same normal table will raise an error
local normal = {}
local meta = {}
meta.__metatable = "Some non-nil value"

setmetatable(normal, meta)
print(getmetatable(normal)) --> table: 0x000000000002f1a0

setmetatable(normal, nil) -- cannot change a protected metatable

fun fact to add onto this you can’t set a table to readonly (table.freeze) if it has a __metatable