User:Merlin11188/Draft

From Legacy Roblox Wiki
Revision as of 21:57, 10 July 2011 by >Merlin11188
Jump to navigationJump to search

Prerequisites


Weak Tables require knowledge of Scope and Metatables.

First off, you must understand what references and objects are. Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.

Weak Tables

Note: all Lua objects in the global environment are ignored and will never be garbage collected, even if they aren't used again.


Weak tables are the mechanism that you use to tell Lua that a reference should not prevent the reclamation of an object by the garbage collector. A weak reference is a reference to an object that is not considered by the garbage collector. If all references pointing to an object are weak, the object is collected and somehow these weak references are deleted. Lua implements weak references as weak tables: A weak table is a table where all references are weak. That means that, if a reference to an object is only held inside weak tables, Lua will collect the object eventually. Tables have keys and values and both may contain any kind of object. Under normal circumstances, the garbage collector does not collect objects that appear as keys or as values of an accessible table. That is, both keys and values are strong references, as they prevent the reclamation of objects to which they refer. In a weak table, keys and values may be weak. That means that there are three kinds of weak tables: tables with weak keys, tables with weak values, and fully weak tables, where both keys and values are weak. Irrespective of the table kind, when a key or a value is collected the whole entry disappears from the table.
The weakness of a table is controlled by the __mode field of its metatable. If the __mode field is a string containing the character 'k', the keys in the table are weak. If __mode contains the character 'v' the values in the table are weak.

Examples


Example
a = {}
b = {}
setmetatable(a, b)
b.__mode = "k"         -- now `a' has weak keys
key = {}               -- creates first key
a[key] = 1
key = {}               -- creates second key
a[key] = 2
collectgarbage()       -- forces a garbage collection cycle
for k, v in pairs(a) do 
    print(v) 
end

Output:
2

What happened there??? Well, the first key is created, then made into an index in table a. Then, the first key is overwritten by the second key, meaning the only reference to the first key is inside table a with a value of 1. Table a has weak keys, so when the garbage collection cycle is forced, it collects the first key because it's only reference is a weak key; however, the second key is still in the global environment, automatically preventing the reclamation of the second key by the garbage collector. So, since the the first key was removed from the table, the whole pair was removed from the table, leaving only the second key and it's corresponding value.

Here's another example, with the value as a reference:

Example
Table={}
setmetatable(Table, {__mode="v"}) -- Set the values as weak
do -- Create a new scope
	local ImAPony=newproxy(true) -- Create a new object in this scope, so the object can be garbage collected.
	Table[1]=ImAPony
end
collectgarbage()
print(Table[1])

Output:
nil

Alright, so we create a table and give it weak values. Then we give it an object as a value (at index/key 1). Since the values with reference to an object are weak, the garbage collector goes ahead and collects the ImAPony userdata.
Now, what would happen if the line setting Table's metatable was commented out? This would happen:

Output:
userdata: [hexadecimal numbers]

The value inside Table is a strong reference, so when the garbage collector made its cycle it didn't pick up the object ImAPony, leaving it at index 1.

See Also

http://www.lua.org/pil/17.html