I have used Python, but now I'm learning Lua because of Torch. The word 'metatable' is really hard to understand for me. For example, is metatable a special kind of table? How does it change the behavior of table?
A metatable is simply a table that is used to control the behavior of another table (or userdata, or other Lua value). A table is a metatable only because it is used as a metatable. That is, being a "metatable" is not a fundamental property of a table. There is no "create_metatable" function or anything. It's just the name we use for a table which is used to control other tables.
Certain operations on tables (or userdata) are specified to check the table's metatable first. If the table (or userdata) has a metatable, and that metatable has a certain key/value pair in it, then the operation will use that key/value pair to perform that operation instead of the normal logic.
Each operation which can be overridden by a metatable has a specific key name associated with it. So if you try to perform addition on a table, the system will look for the __add
key in the metatable in order to access it.
The value in the pair is usually (though not always) a function. Such functions are generally called "metafunctions". The parameters it takes and the meaning of its return value is defined by the particular operation calling it. A few operations allow the value to be a table or something else.
In Lua, you assign a metatable to a table (but not userdata) with the setmetatable
function. From C, you use the lua_setmetatable
function to assign a table (or userdata) a metatable.
Metatables are particularly important for C code that exposes C objects as userdata. Raw userdata is just an opaque blob of bits; Lua defines very few legal operations that can be performed on them by default. But by assigning them a metatable, you can give the userdata more abilities through metafunctions.
Note that Lua values other than tables and userdata can have metatables. However, unlike tables and userdata, values of each Lua type all share the same metatable for that type. So all strings have the same metatable, all numbers have the same metatable, etc.
Hello
After a while of reading and understanding what a metatable could be i like to post a working example. So everybody can see and feel how usefull it can be. The example change the # operator for the associated table. Because i realized # counts only correct not named keys. # ignores also 0 and negative numbers. And here is the working example how to replace it with a function that counts every table correct...
# lua
Lua 5.3.5 Copyright (C) 1994-2018 Lua.org, PUC-Rio
> -- Defining a table with 3 key/value pairs
> my_table={[0]=0,[1]=1,['metatable']={}}
> #my_table
1
> -- # is counting wrong it counts only my_table[1]
> -- Now set the empty my_table.metatable to my_table
> setmetatable(my_table,my_table.metatable)
> -- So it can be accessed without getmetatable()
> -- Now replacing # for associated table my_table
> -- in my_table.metatable with the metafuncion __len
> my_table.metatable.__len=function(array) local incr=0 for _ in pairs(array) do incr=incr+1 end return incr end
> -- Let's test # ...
> #my_table
3
> -- Now # is usefull because it counts correct
> -- And my_table.metatable can be set as a metatable for other tables
> -- where # is counting wrong but needed to count the correct way
> #_G
0
> setmetatable(_G,my_table.metatable)
> #_G
45
> #package.loaded
0
> setmetatable(package.loaded,my_table.metatable)
> #package.loaded
12
> -- Like _G or package.loaded for example
nil
entry). That's its job. –
Ovenbird © 2022 - 2024 — McMap. All rights reserved.
__index
is used in object-oriented Lua. – Devilfish