generic image
Processing...
  • Games
  • Catalog
  • Develop
  • Robux
  • Search in Players
  • Search in Games
  • Search in Catalog
  • Search in Groups
  • Search in Library
  • Log In
  • Sign Up
  • Games
  • Catalog
  • Develop
  • Robux
We use cookies to offer you a better experience. By using Roblox.com, you are agreeing to our Privacy and Cookie Policy.
   
ROBLOX Forum » Game Creation and Development » Scripting Helpers
Home Search
 

Arithmetic Metamethods

Previous Thread :: Next Thread 
ArticShifter is not online. ArticShifter
Joined: 19 Jan 2012
Total Posts: 148
25 Jul 2012 07:20 PM
I will introduce a simple example to explain how to use metatables. Suppose we are using tables to represent sets, with functions to compute the union of two sets, intersection, and the like. As we did with lists, we store these functions inside a table and we define a constructor to create new sets:

Set = {}

function Set.new (t)
local set = {}
for _, l in ipairs(t) do set[l] = true end
return set
end

function Set.union (a,b)
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end

function Set.intersection (a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end

To help checking our examples, we also define a function to print sets:
function Set.tostring (set)
local s = "{"
local sep = ""
for e in pairs(set) do
s = s .. sep .. e
sep = ", "
end
return s .. "}"
end

function Set.print (s)
print(Set.tostring(s))
end

Now, we want to make the addition operator (`+´) compute the union of two sets. For that, we will arrange that all tables representing sets share a metatable and this metatable will define how they react to the addition operator. Our first step is to create a regular table that we will use as the metatable for sets. To avoid polluting our namespace, we will store it in the Set table:

Set.mt = {} -- metatable for sets

The next step is to modify the Set.new function, which creates sets. The new version has only one extra line, which sets mt as the metatable for the tables that it creates:
function Set.new (t) -- 2nd version
local set = {}
setmetatable(set, Set.mt)
for _, l in ipairs(t) do set[l] = true end
return set
end

After that, every set we create with Set.new will have that same table as its metatable:
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
print(getmetatable(s1)) --> table: 00672B90
print(getmetatable(s2)) --> table: 00672B60

Finally, we add to the metatable the so-called metamethod, a field __add that describes how to perform the union:

Set.mt.__add = Set.union

Whenever Lua tries to add two sets, it will call this function, with the two operands as arguments.
With the metamethod in place, we can use the addition operator to do set unions:

s3 = s1 + s2
Set.print(s3) --> {1, 10, 20, 30, 50}

Similarly, we may use the multiplication operator to perform set intersection:
Set.mt.__mul = Set.intersection

Set.print((s1 + s2)*s1) --> {10, 20, 30, 50}

For each arithmetic operator there is a corresponding field name in a metatable. Besides __add and __mul, there are __sub (for subtraction), __div (for division), __unm (for negation), and __pow (for exponentiation). We may define also the field __concat, to define a behavior for the concatenation operator.

When we add two sets, there is no question about what metatable to use. However, we may write an expression that mixes two values with different metatables, for instance like this:

s = Set.new{1,2,3}
s = s + 8

To choose a metamethod, Lua does the following: (1) If the first value has a metatable with an __add field, Lua uses this value as the metamethod, independently of the second value; (2) otherwise, if the second value has a metatable with an __add field, Lua uses this value as the metamethod; (3) otherwise, Lua raises an error. Therefore, the last example will call Set.union, as will the expressions 10 + s and "hy" + s.
Lua does not care about those mixed types, but our implementation does. If we run the s = s + 8 example, the error we get will be inside Set.union:

bad argument #1 to `pairs' (table expected, got number)

Report Abuse
ElectricBlaze is not online. ElectricBlaze
Joined: 18 Jul 2011
Total Posts: 22930
25 Jul 2012 07:23 PM
...You just copied this from the Lua website.
Report Abuse
Previous Thread :: Next Thread 
Page 1 of 1
 
 
ROBLOX Forum » Game Creation and Development » Scripting Helpers
   
 
   
  • About Us
  • Jobs
  • Blog
  • Parents
  • Help
  • Terms
  • Privacy

©2017 Roblox Corporation. Roblox, the Roblox logo, Robux, Bloxy, and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.



Progress
Starting Roblox...
Connecting to Players...
R R

Roblox is now loading. Get ready to play!

R R

You're moments away from getting into the game!

Click here for help

Check Remember my choice and click Launch Application in the dialog box above to join games faster in the future!

Gameplay sponsored by:
Loading 0% - Starting game...
Get more with Builders Club! Join Builders Club
Choose Your Avatar
I have an account
generic image