I can't say I've ever heard of strong tables before so I can't provide much insight for that. Weak tables however I understand a bit better.
The first thing I'll say is that weak tables have limited uses. If you find yourself trying to use them when there's a another solution you're probably just making life more difficult for yourself. That being said, when using them correctly they're extremely useful.
I think the most important line from the wiki in regards to weak tables is the following:
"If a reference to an object is only held inside weak tables, Lua will collect the object eventually."
What this means is that depending on our mode if the keys or values or one of the two (both) aren't referenced anywhere else in the active code their entry will be removed from the table.
Let's look at some examples:
Note: the garbage may not collect in the 1 second interval so if having difficulties either run again or change the wait time.
01 | local t = setmetatable ( { } , { __mode = "k" } ); |
02 | local k = game.Workspace.Part; |
05 | for k, v in next , t do print (k, v); end |
09 | for k, v in next , t do print (k, v); end |
11 | for k, v in next , t do print (k, v); end |
Now looking at values:
01 | local t = setmetatable ( { } , { __mode = "v" } ); |
02 | local v = game.Workspace.Part; |
05 | for k, v in next , t do print (k, v); end |
09 | for k, v in next , t do print (k, v); end |
11 | for k, v in next , t do print (k, v); end |
Finally keys and values:
01 | local t = setmetatable ( { } , { __mode = "kv" } ); |
02 | local k = game.Workspace.Part 1 ; |
03 | local v = game.Workspace.Part 2 ; |
06 | for k, v in next , t do print (k, v); end |
10 | for k, v in next , t do print (k, v); end |
12 | for k, v in next , t do print (k, v); end |
17 | local t = setmetatable ( { } , { __mode = "kv" } ); |
18 | local k = game.Workspace.Part 1 ; |
19 | local v = game.Workspace.Part 2 ; |
22 | for k, v in next , t do print (k, v); end |
26 | for k, v in next , t do print (k, v); end |
28 | for k, v in next , t do print (k, v); end |
I think the main thing you need to be wary other than setting variables to nil explicitly is scope. If you create entries in a table using variables that are local in scope they will become nil when you leave that scope. Here's what I mean:
01 | local t = setmetatable ( { } , { __mode = "k" } ); |
05 | local k = game.Workspace.Part; |
10 | for k, v in next , t do print (k, v); end |
15 | for k, v in next , t do print (k, v); end |
So when is this useful? I personally have found this most useful for OOP (object oriented programming). We can use weak-tables to store private-values that we don't want the user to mess with in the class.
Here's an example:
02 | local class_mt = { __index = class } ; |
03 | local class_ref = setmetatable ( { } , { __mode = "k" } ); |
05 | function class.new(x, y) |
09 | self = setmetatable (self, class_mt); |
11 | class_ref [ self ] .magnitude = math.sqrt(x*x + y*y); |
15 | function class:getMagnitude() |
16 | return class_ref [ self ] .magnitude; |
19 | local a = class.new( 1 , 2 , 3 ); |
20 | local b = class.new(- 3 , 7 , 32 / 4 *(- 8 )); |
23 | print (a:getMagnitude()); |
26 | for k, v in next , class_ref do print (k, v); end |
34 | for k, v in next , class_ref do print (k, v); end |
Of course these "private" values could be accessed as long as the programmer has access to the class_ref
table, but if you're writing your class in a module then it's as simple as not returning said table. I use this exact technique to store cframe components in my lua cframe class.
Hope this helped clear some stuff up.