Skip to content

Commit 8f6398b

Browse files
committed
started with metatables tutorial
1 parent dad4760 commit 8f6398b

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

98.8 KB
Loading

tutorials/metatables/metatables.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Lua Metatables
2+
3+
Lua is a minimalistic but powerful scripting language, that only provides few smart mechanisms and doesn't anything,
4+
which gives us a lot of freedom. One of these mechanisms is the *metatable*. I don't even know if other languages have
5+
such thing. Some people think that *metatables* are the Lua *classes*, but that is not really true. Yes, you can mimic OOP
6+
using *metatables*, but as mentioned before Lua doesn't enforce anything and you can use them for whatever you can think of.
7+
8+
It is very helpful if you, the reader, have already understood ...
9+
10+
- tables
11+
- functions
12+
- nil
13+
14+
... otherwise this *metatable* introduction won't make much sense.
15+
16+
## The Basics
17+
18+
A *metatable* (let's call it `M`), is also just a simple table, but with [specific indices](https://www.lua.org/manual/5.4/manual.html#2.4)
19+
and it has to be declared to be the *metatable* of "another" table (let's call that `T`) using the `setmetatable(T,M)` function. These specific
20+
indices or metatable elements act as events. And when one of these events is triggered then Lua can execute something.
21+
You can simply treat these indices as reserved for Lua metatables, and therefore not use them for anything else but
22+
metatables, otherwise you would confuse people reading your code, and probably yourself too.
23+
24+
Let's see which events exist, and what would trigger these events.
25+
26+
- `__index` ➞ when you are accessing a key/index that is not present in the table T.
27+
- `__newindex` ➞ when you are trying to create a new key/index inside the table T
28+
- `__call` ➞ when you are calling a table like a function `T()`.
29+
- Operators ➞ When you use an operator on 1 or 2 tables ...
30+
- `__add``t1 + t2`
31+
- `__sub``t1 - t2`
32+
- `__mul``t1 * t2`
33+
- `__div``t1 / t2`
34+
- `__mod``t1 % t2`
35+
- `__pow``t1 ^ t2`
36+
- `__unm``-t1`
37+
- `__idiv``t1 // t2`
38+
- `__band``t1 & t2`
39+
- `__bor``t1 | t2`
40+
- `__bxor``t1 ~ t2`
41+
- `__bnot``~t1`
42+
- `__shl``t1 << n`
43+
- `__shr``t1 >> n`
44+
- `__concat``t1 .. t2`
45+
- `__len``#t1`
46+
- `__eq``t1 == t2`
47+
- `__lt``t1 < t2`
48+
- `__le``t1 <= t2`
49+
50+
Okay, now let's write a small and almost finished code example that shows how to create a *metatable* and how to use `setmetatable()`.
51+
52+
T = { }
53+
54+
M =
55+
{
56+
__index = <placeholder>,
57+
__newindex = <placeholder>,
58+
__call = <placeholder>,
59+
__add = <placeholder>,
60+
}
61+
62+
setmetatable(T, M)
63+
64+
![setmetatable](img/setmetatable.png)
65+
66+
67+
Now we have a metatable `M` that **is connected** to the table `T`. We defined some events in our *metatable*, so that it's clear
68+
**when** to do something. And now only the actions are missing. The `<placeholder>`s are the actions - the "**what** to do"s.
69+
And what do we usually associate with actions? - functions. All of them can be functions, but `__index` and `__newindex`
70+
can also be tables instead of functions, which is actually pretty common.
71+
But for now let's focus on the functions, that only print some text, and let's try to trigger these events.
72+
73+
T = { }
74+
75+
M =
76+
{
77+
__index = function() print("this key does not exist in table T") end,
78+
__newindex = function() print("you want to create a new key in table T") end,
79+
__call = function() print("you are calling T like a function") end,
80+
__add = function() print("you are using the + operator") end,
81+
}
82+
83+
setmetatable(T, M)
84+
85+
-- trigger the __index event by accessing a non-existing index
86+
local Foo = T.foo
87+
88+
-- trigger the __newindex event by creating a new index
89+
T.foo = 123
90+
91+
-- trigger the __call event by calling the table like a function
92+
T()
93+
94+
-- trigger the __add event by providing tables as operands to the plus operator
95+
local Sum = T + T
96+
97+
98+
If you execute this it prints ...
99+
100+
this key does not exist in table T
101+
you want to create a new key in table T
102+
you are calling T like a function
103+
you are using the + operator
104+
105+
106+
Now we have learned the very basics of *metatables*, but this is the most important part, because it explains the event
107+
concept. At the moment the functions don't do much except for the printing, and therefore we will learn in the next chapter
108+
about the parameters of the *"event-action"* functions we just created.
109+

0 commit comments

Comments
 (0)