Can anybody tell me why code1 and code2 have different results but code3 and code4 have the same.
code1:
o = {x = "hi"}
mt = {}
mt.__gc = function (o) print(o.x) end
setmetatable(o, mt)
o = nil
collectgarbage()
The result of code1:
hi
code2:
o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__gc = function (o) print(o.x) end
o = nil
collectgarbage()
The result of code2:nothing
The only difference between code1 and code2 is that the statement setmetatable(o, mt)
and the statement mt.__gc = function (o) print(o.x) end
are executed in different order. Their results are totally different: the first one printed hi while the other printed nothing. Does the order of setting meta-table to a object finally affect the result? if it does, why code3 and code4 have the same result?
code3
o = {x = "hi"}
mt = {}
setmetatable(o, mt)
mt.__index = function () print("no such key") end
print(o["x"])
print(o["y"])
code4
o = {x = "hi"}
mt = {}
mt.__index = function () print("no such key") end
setmetatable(o, mt)
print(o["x"])
print(o["y"])
Both the result of code3 and code4 are the same:
hi
no such key
nil
Since Lua 5.2, Lua tables support metamethod __gc. Quoth the second paragraph:
For an object (table or userdata) to be finalized when collected, you must mark it for finalization. You mark an object for finalization when you set its metatable and the metatable has a field indexed by the string "
__gc
". Note that if you set a metatable without a__gc
field and later create that field in the metatable, the object will not be marked for finalization.
This is exactly your case: the second sentence describes the first example, the third, the second.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With