Difference between revisions of "Lua: Metamethods"

From Mario Fan Games Galaxy Wiki
m
m
 
Line 2: Line 2:
 
'''Metamethods''' are special variables (generally functions) that are called during some [[Lua: Tables|table]] and other datatype operations. They are important because they define the behavior of a table when [[Lua]] would otherwise not know how to handle it in that case. An operation between two tables may succeed even if one of the tables doesn't have the relevant metamethod, as Lua will use the metamethod of the table on the left side of the operand to decide the behavior; if that fails, it will try the one on the right{{emdash}}only when both attempts fail will it generate an error. In the case of conflicting metamethods, the one on the left will win out.
 
'''Metamethods''' are special variables (generally functions) that are called during some [[Lua: Tables|table]] and other datatype operations. They are important because they define the behavior of a table when [[Lua]] would otherwise not know how to handle it in that case. An operation between two tables may succeed even if one of the tables doesn't have the relevant metamethod, as Lua will use the metamethod of the table on the left side of the operand to decide the behavior; if that fails, it will try the one on the right{{emdash}}only when both attempts fail will it generate an error. In the case of conflicting metamethods, the one on the left will win out.
  
Although tables are not the only data structures that can have metatables, they are the only ones intended for programmers to change within Lua itself. Therefore, these lists will only make mention of their use on tables. It is important to note that a metamethod will not call other metamethods, but a single operation may cause more than one metamethod to be executed.
+
Although tables are not the only data structures that can have metatables (in fact all of them can, even <tt>nil</tt>), they are the only ones that can have metatables added or removed without using the debug library. However, though it is possible to modify, for example, the strings' metatable without the debug library, some behavior such as concatenation is hardcoded and cannot be overridden.
  
Metamethods should be "transparent" if applicable; that is, a given operation on tables should behave like it would with other datatypes.
+
Whenever possible, overridden operators should have meaning that is predictable or similar to what is normally understood for that operator. Therefore, you may consider using <tt>+</tt> for field-wise addition rather than concatenation, using <tt>..</tt> for the latter operation.
 +
 
 +
Metamethods are also known as ''metafields'', which is a more accurate term for the few that are in fact just normal values and not functions.
 
===Current Metamethods===
 
===Current Metamethods===
 
''As of Lua 5.1.4, also includes parameters passed to the metamethod''
 
''As of Lua 5.1.4, also includes parameters passed to the metamethod''
 +
{| style="border: 2px solid #aac; background-color: #fff; font-size: 90%; text-align: center;" cellpadding="3"
 +
|- style="font-size:110%; text-align: center; background-color: #ccccff;"
 +
! Name
 +
! Kind
 +
! Arguments/Value
 +
! Triggered by
 +
! Notes
 +
|-
 +
! __add
 +
| Method
 +
| (self, right)
 +
| ''self'' + ''right''
 +
|
 +
|-
 +
! __sub
 +
| Method
 +
| (self, right)
 +
| ''self'' - ''right''
 +
|
 +
|-
 +
! __mul
 +
| Method
 +
| (self, right)
 +
| ''self'' * ''right''
 +
|
 +
|-
 +
! __div
 +
| Method
 +
| (self, right)
 +
| ''self'' / ''right''
 +
|
 +
|-
 +
! __mod
 +
| Method
 +
| (self, right)
 +
| ''self'' % ''right''
 +
|
 +
|-
 +
! __pow
 +
| Method
 +
| (self, right)
 +
| ''self'' * ''right''
 +
|
 +
|-
 +
! __unm
 +
| Method
 +
| (self)
 +
| -''self''
 +
|
 +
|-
 +
! __concat
 +
| Method
 +
| (self, right)
 +
| ''self'' .. ''right''
 +
|
 +
|-
 +
! __eq
 +
| Method
 +
| (self, right)
 +
| ''self'' == ''right''
 +
| 1
 +
|-
 +
! __lt
 +
| Method
 +
| (self, right)
 +
| ''self'' < ''right''
 +
| 2
 +
|-
 +
! __le
 +
| Method
 +
| (self, right)
 +
| ''self'' <= ''right''
 +
| 3
 +
|-
 +
! __index
 +
| Method
 +
| (self, key)
 +
| ''self''[''key'']
 +
| 4, 5
 +
|-
 +
! __newindex
 +
| Method
 +
| (self, key, value)
 +
| ''self''[''key''] = ''value''
 +
| 4, 6
 +
|-
 +
! __tostring
 +
| Method
 +
| (self)
 +
| tostring(''self'')
 +
|
 +
|-
 +
! __call
 +
| Method
 +
| (self, ...)
 +
| ''self''(...)
 +
| 7
 +
|-
 +
! __metatable
 +
| Any value
 +
| [returned value]
 +
| getmetatable(''self'')
 +
|
 +
|-
 +
! __mode
 +
| String
 +
| "k", "v", or "kv"
 +
|
 +
|
 +
|-
 +
! __gc
 +
| Method
 +
| (self)
 +
| [when collectible]
 +
| 8
 +
|-
 +
! __len
 +
| Method
 +
| (self)
 +
| #''self''
 +
| 9
 +
|-
 +
! __pairs
 +
| Method
 +
| (self)
 +
| pairs(''self'')
 +
| 9
 +
|-
 +
! __ipairs
 +
| Method
 +
| (self)
 +
| ipairs(''self'')
 +
| 9
 +
|-
 +
|}
 +
# Operands must be the same type and share the same <tt>__eq</tt> metamethod. Bypassable by <tt>rawequal()</tt>
 +
# Also called by <tt>''self'' > ''right''</tt>, but with the operands flipped. Operands must be same type
 +
# Also called by <tt>''self'' >= ''right''</tt>, but with the operands flipped. Operands must be same type
 +
# Triggered only if the specified <tt>key</tt> does not exist
 +
# Bypassable by <tt>rawget()</tt>
 +
# Bypassable by <tt>rawset()</tt>
 +
# <tt>__call</tt> may have extra parameters after the <tt>self</tt> reference
 +
# Userdata only, used to free resources allocated by the userdata before collection
 +
# Lua 5.2 required
  
'''Arithmetic'''
+
Further details of <tt>__metatable</tt> and <tt>__mode</tt> are specified on the [[Lua: Metatables|Metatables]] and [[Lua: Weak Tables|Weak Tables]] pages, respectively.
*'''__add (op1, op2)''': called during an attempt to perform addition (+) on a table. Must be a function.
 
*'''__sub (op1, op2)''': called during an attempt to perform subtraction (-) on a table. Must be a function.
 
*'''__mul (op1, op2)''': called during an attempt to perform multiplication (*) on a table. Must be a function.
 
*'''__div (op1, op2)''': called during an attempt to perform division (/) on a table. Must be a function.
 
*'''__mod (op1, op2)''': called during an attempt to perform modulus division (%) on a table. Must be a function.
 
*'''__pow (op1, op2)''': called during an attempt to perform exponentiation (^) on a table. Must be a function.
 
*'''__unm (op1)''': called during an attempt to negate (-) a table. Must be a function.
 
*'''__concat(op1, op2)''': called during an attempt to concatenate (..) a table. Must be a function.
 
'''Comparison'''
 
*'''__eq (op1, op2)''': called during an attempt to compare equal-to (==).
 
*'''__lt (op1, op2)''': called during an attempt to compare less-than (<). Greater-than also calls this metamethod, but with the operands reversed.
 
*'''__le (op1, op2)''': called during an attempt to compare less-than-or-equal-to (<=). Greater-than-or-equal-to also calls this metamethod, but with the operands reversed.
 
 
 
'''Indexing'''
 
*'''__index (table, key)''': called during an attempt to access a nonexistent index. May be a function, or another table to look in instead. Bypassed by the '''rawget''' function.
 
*'''__newindex (table, key, value)''': called during an attempt to write to a nonexistent index. Bypassed by the '''rawset''' function.
 
 
 
'''Other'''
 
*'''__tostring (table)''': called during an attempt to coerce the table into a string, such as by concatenating it with another string or by using the '''print''' function on it.
 
*'''__call (table)''': called during an attempt to call a table as if it were a function.
 
*'''__metatable''': essentially "locks" and hides the metatable for a given table so it can't be changed; functions like '''setmetatable''' will return the value of this instead of the actual metatable reference. Not actually a method.
 
*'''__mode''': Changes the weakness setting of a table, which determines if the keys or values (or both) are ignored as references when the data they reference is collected. In other words, the garbage collector will collect an object if only weak references are referencing it (or there are no references). The value is a string, either "k", "v", or "kv" (or "vk"); if this field is nil, the table behaves normally. Not actually a method.
 
*'''__gc ()''': called for userdata, instructs Lua as to how to release other resources the userdata may be using.
 
===Future Metamethods===
 
''Note: these have not totally been confirmed for Lua 5.2, so whether or not they will be implemented is unknown''
 
 
 
*'''__len (table)''': called during an attempt to use the length operator (#). Must be a function. ''Lua 5.2+''
 
<!-- *'''__pairs''': -->
 
<!-- *'''__ipairs''': -->
 

Latest revision as of 23:21, 2 April 2010

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.

Metamethods are special variables (generally functions) that are called during some table and other datatype operations. They are important because they define the behavior of a table when Lua would otherwise not know how to handle it in that case. An operation between two tables may succeed even if one of the tables doesn't have the relevant metamethod, as Lua will use the metamethod of the table on the left side of the operand to decide the behavior; if that fails, it will try the one on the right—only when both attempts fail will it generate an error. In the case of conflicting metamethods, the one on the left will win out.

Although tables are not the only data structures that can have metatables (in fact all of them can, even nil), they are the only ones that can have metatables added or removed without using the debug library. However, though it is possible to modify, for example, the strings' metatable without the debug library, some behavior such as concatenation is hardcoded and cannot be overridden.

Whenever possible, overridden operators should have meaning that is predictable or similar to what is normally understood for that operator. Therefore, you may consider using + for field-wise addition rather than concatenation, using .. for the latter operation.

Metamethods are also known as metafields, which is a more accurate term for the few that are in fact just normal values and not functions.

Current Metamethods

As of Lua 5.1.4, also includes parameters passed to the metamethod

Name Kind Arguments/Value Triggered by Notes
__add Method (self, right) self + right
__sub Method (self, right) self - right
__mul Method (self, right) self * right
__div Method (self, right) self / right
__mod Method (self, right) self % right
__pow Method (self, right) self * right
__unm Method (self) -self
__concat Method (self, right) self .. right
__eq Method (self, right) self == right 1
__lt Method (self, right) self < right 2
__le Method (self, right) self <= right 3
__index Method (self, key) self[key] 4, 5
__newindex Method (self, key, value) self[key] = value 4, 6
__tostring Method (self) tostring(self)
__call Method (self, ...) self(...) 7
__metatable Any value [returned value] getmetatable(self)
__mode String "k", "v", or "kv"
__gc Method (self) [when collectible] 8
__len Method (self) #self 9
__pairs Method (self) pairs(self) 9
__ipairs Method (self) ipairs(self) 9
  1. Operands must be the same type and share the same __eq metamethod. Bypassable by rawequal()
  2. Also called by self > right, but with the operands flipped. Operands must be same type
  3. Also called by self >= right, but with the operands flipped. Operands must be same type
  4. Triggered only if the specified key does not exist
  5. Bypassable by rawget()
  6. Bypassable by rawset()
  7. __call may have extra parameters after the self reference
  8. Userdata only, used to free resources allocated by the userdata before collection
  9. Lua 5.2 required

Further details of __metatable and __mode are specified on the Metatables and Weak Tables pages, respectively.