|
| 05 Jun 2014 08:26 PM |
Every time I spot a metatables, I only see it being used to run a function when a new value is added to a table.
What else can they be used for?
|
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:28 PM |
OOP, sandboxing, controlling how the table acts with operators, etc.
Example, printing (or tostringing) a table to get all the numbers inside added up:
x = {1, 2, 3}; setmetatable(x, {__tostring = function(self) local total = 0; for key = 1, #self do total = total + tonumber(self[key]) end return total end;});
print(x); --6 |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:31 PM |
| To be safe you should do: + tonumber(self[key]) or 0 |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 08:39 PM |
You said it returns 6
So does that mean, metatable functions are ran right away, as soon as they're read?
You can't call the function in it? |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 08:41 PM |
Internally, the print() function calls an object's __tostring metamethod. What cnt is doing is overriding the original __tostring and customizing it to suit his needs.
-[::ƧѡÎḾḠΰῩ::]-[::Helper of Scripting and Writer of Wikis::]- |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 08:50 PM |
Oh, wow! I didn't realize tables had metamethods. I just looked it up, and it's pretty awesome what you can do with them!
However, can metatables only use functions that are metamethods, or can you use other things too?
Also, would this work then?
PartSpawn = setmetatable({}, { __index = function(self,key) if key == "Part" then local Part = Instance.new("Part",Workspace) Part.Anchored = true Part.Size = Vector3.new(3,3,3) Part.Position = Vector3.new(0,40,0) return Part end end })
PartSpawn.Part.BrickColor = BrickColor.new("Lime green") PartSpawn.Part.BrickColor = BrickColor.new("Bright blue") PartSpawn.Part.Name = "Magic" |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:51 PM |
'So does that mean, metatable functions are ran right away, as soon as they're read?' What? They are invoked when something happens. Like __add is invoked when you use the sum operator and so forth.
'You can't call the function in it?' You can, but why would you want to?
You could technically do this for whatever reason you wanted to: print(getmetatable(x).__tostring(x)); |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:52 PM |
You can store whatever you want in a metatable, not only metamethods.
And your script should work fine. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:53 PM |
| To make things more interesting, you can attach a metatable to a metatable if you want. |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 08:54 PM |
A METATABLE TO A METATABLE?!??!
Cnt, you're giving me like, panic attacks here.
I can't comprehend even one metatable e.o
So, if you had attached a metatable to a metatable, would the double nested metatable edit the first metatable, or the regular table? |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 08:57 PM |
Let's call regular table A, metatable of A B, and metatable of B C metamethod in B invoked when you do something with A metamethod in C invoked when you do something with B
You can treat a metatable as a regular table, because it is a table. |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 08:58 PM |
Giving a metatable a metatable is practically useless, because one does not typically add new keys to a metatable after it has been assigned to a table.
Boy was that a mouth-full. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
| |
|
|
| 05 Jun 2014 09:03 PM |
So, just curious then. How would I set a metatable to my PartSpawn table?
Would I do
bob = setmetatable(getmetatable(PartSpawn),{}) |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 09:05 PM |
That's if you want to set a metatable to the metatable of PartSpawn. I see no reason why you would want to but yeah. If you want to set a metatable to the table itself, setmetatable(PartSpawn, {});
Also, setmetatable returns the table you are attaching it to (the first argument) not the metatable itself. So be careful |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 09:07 PM |
Alright, but if you don't mind, can you give me an example of a metatable that hold's a function, that doesn't use a metamethod?
|
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 09:08 PM |
local regularTable = setmetatable({}, {randomFunction = function() print("a"); end;});
getmetatable(regularTable).randomFunction(); --a |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 09:12 PM |
Oh, alright, thanks!
So, metatables can also be a neat little way to store functions?
That's cool ;o And it makes table-modifying really neat aswell
Thanks cnt, swim, and Agent.
You guys really helped me.
Time to play with metatables ;p |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 09:18 PM |
If you want to hide functions which can only be accessed by reference you can do something like:
local tbl = setmetatable({}, {});
do local metatable = getmetatable(tbl); metatable.__metatable = false; --can't use getmetatable to get the metatable metatable.secret= function() print("Hi") end; metatable.secret(); --Hi end
metatable.secret(); --metatable is nil
getmeteatable(tbl).secret(); --index boolean error |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 09:28 PM |
Wow, that's really neat!
Also, if the table is global, does that automatically make the metatable global?
|
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 05 Jun 2014 09:32 PM |
No. I think you are over-thinking this. A metatable is just a table, if the table is global but you reference the table (that you plan to attach as the metatable) local, the table you planned to attach is local. getmetatable literally returns a table (the second argument of setmetatable) |
|
|
| Report Abuse |
|
|
|
| 05 Jun 2014 09:36 PM |
Alrighty.
Thanks!
I'm gonna make something neat with metatables and show you one day :D |
|
|
| Report Abuse |
|
|