I have never understood how to use metatables, nor seen any use for them. Can someone give me an example of what a metatable would do in terms of roblox games? What can you do that REQUIRES that you have a metatable?
pluginfactory's answer tells you how to use metamethods. There are a number of things that you can do with them - all about making scripting easier (or at least differently).
One major thing you can do is make classes. Examples of Roblox classes include the Player
class or the Part
class. ex, when you do Instance.new("Part")
, you have created an "instance" of type/class "Part". In a single Roblox place there will usually be hundreds or thousands of Part
instances, but only one Part
class. You can create your own classes if you like (see the articles on Lua Object Oriented Programming; consider looking at the first two articles and any of the ones under Feature Implementations.)
With metamethods, you can add a variety of OOP (Object Oriented Programming) features, like:
Properties. A property looks like a variable, but when you get or set its value, it runs a function. This could be used, for example, when changing a single value requires other values to be changed with it.
Inheritance. When one class inherits
from another, it receives all the functions, properties, and events of its parent/derived class and can add its own. In Roblox, Part inherits from BasePart, which itself inherits from PVInstance, which inherits from Instance. Instance has the fewest properties; PVInstance adds more, and so on.
Immutability. Sometimes you want an object whose variables cannot be changed by any other bit of code (that is the definition of immutable). Metamethods can be used to make sure this happens.
Memory management. Sometimes you want to collect a list of items, but if the item is deleted from the workspace and no other code knows about the item anymore, you don't want it part of your list either. This requires the __mode
metamethod. The list of items I described is a weak table.
Making an object have mathematical properties. Using __add
, for instance, will let you add things to that object using +
, ex. myObj + myOtherObj
. This is best used for things that make sense to be added to each other. The link pluginfactory gave gives a good explanation of this use.
(There is also a few other properties you can add to an object - for instance, the __tostring
metamethod, which allows you to specify how an object should be converted into a string.)
Of the things I've listed, most of those things you can use different code to accomplish.
if
statements to determine which function to use. (Alternatively, give the object an Add
function and use that.)So, overall, there are a few things that cannot really be done without metatables. Whether you will need to use those features depends on how complex your game is.
They are attached to data and contain values called metamethods. Metamethods are fired when a certain action is used with the datum that it is attached to.
It should be noted that when writing functions for either arithmetic or relational metamethods the two function parameters are interchangeable between the table that fired the metamethod and the other value
Example
local x = {} local metaTable = {} -- metaTables are tables, too! setmetatable(x, metaTable) -- Give x a metatable called metaTable! print(getmetatable(x)) --> table: [hexadecimal memory address]
Or
local metatable = { __call = function(t, param) local sum = {} for i, value in ipairs(t) do sum[i] = value + param -- Add the argument (5) to the value, then place it in the new table (t). end return unpack(sum) -- Return the individual table values end } local t = setmetatable({10, 20, 30}, metatable) print(t(5)) --> 15 25 35