Difference between revisions of "Lua: Metatables"

From Mario Fan Games Galaxy Wiki
(Cleaning up)
m (...um, wow. also those comments should probably be numbered and moved to the end since they break the flow of the code)
Line 19: Line 19:
 
== Example code ==
 
== Example code ==
 
<div style='width: 60%; margin-left: 5%; background: #f8f8f8; border: 1px solid #444; padding: 8px;'><source lang="lua" enclose="div">function newTable(t_data)
 
<div style='width: 60%; margin-left: 5%; background: #f8f8f8; border: 1px solid #444; padding: 8px;'><source lang="lua" enclose="div">function newTable(t_data)
   return setmetatable(t_data, mt) -- Assigns the same metatable to every table made with this function
+
   return setmetatable(t_data, mt) -- Assigns the same metatable to the table passed to this function
 
end
 
end
  
 
metatable = {  
 
metatable = {  
 
     __add = function (a, b)
 
     __add = function (a, b)
         local sum = newTable { } -- This is the value we will be returning.
+
         local sum = { } -- This is the new table we will be returning.
         for i = 1, math.max(#a, #b) do -- runs as long as entries exist in the larger table
+
         for i = 1, math.max(#a, #b) do -- Runs as long as entries exist in the larger table
             sum[i] = (a[i] or 0) + (b[i] or 0) -- adds one table entry to its correspondent
+
             sum[i] = (a[i] or 0) + (b[i] or 0) -- Adds one table entry to its correspondent, using 0 for entries that don't exist
 
         end
 
         end
         return sum
+
         return newTable(sum) -- Set the metatable or we can't use this table for future addition operations!
 
     end,
 
     end,
  
 
     __tostring = function (t)
 
     __tostring = function (t)
         return table.concat(t, " ")
+
         return table.concat(t, " ") -- Control how this table is coerced into a string
 
     end,
 
     end,
 
}
 
}

Revision as of 02:08, 6 October 2009

Lua
Lua.gif
Basics
Intermediate
Advanced
XLua
Add to this template
 Standardwikimessagebox.png This article assumes the use of Lua 5.1.

Information may not be accurate or may need revision if you are using a different version.

Metatables are a form of table that may be attached to any other table, including itself.

An individual table may only have one metatable attached, but that metatable may have its own metatable, and this may be cascaded indefinitely. An individual metatable may be attached to any number of tables, however.

The primary purpose of metatables is to allow tables to be added together, an operation that is by default impossible.

table1 = {1, 2, 3}
table2 = {10, 20, 30}
table3 = table1 + table2 -- Returns an error


Because tables may contain any number of separate non-nil types of data, adding tables is by default impossible, and will always return an error, due to the overall impracticality of doing so.

To allow tables to be added together, the metamethod __add must be defined within a metatable, and that metatable must then be appended to a regular table:

Example code

function newTable(t_data)
  return setmetatable(t_data, mt) -- Assigns the same metatable to the table passed to this function
end

metatable = { 
    __add = function (a, b)
        local sum = { } -- This is the new table we will be returning.
        for i = 1, math.max(#a, #b) do -- Runs as long as entries exist in the larger table
            sum[i] = (a[i] or 0) + (b[i] or 0) -- Adds one table entry to its correspondent, using 0 for entries that don't exist
        end
        return newTable(sum) -- Set the metatable or we can't use this table for future addition operations!
    end,

    __tostring = function (t)
        return table.concat(t, " ") -- Control how this table is coerced into a string
    end,
}

table1 = newTable {1, 2, 3}
table2 = newTable {10, 20, 30}
table3 = table1 + table2 -- valid after much headache

print(table3) -- Was it worth it?