From 655ce78eeed2bfebc13666f4bb394c9436ad7ca1 Mon Sep 17 00:00:00 2001 From: EndMove Date: Sun, 15 Jan 2023 12:54:58 +0100 Subject: [PATCH] metatables and metamethods --- README.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3f93226..bcad025 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Use this table of contents to travel more easily through this cheat sheet. - [Advanced](#advanced) - [Tables, Array, dict..](#tables-array-dict) - [Metatables and metamethods](#metatables-and-metamethods) - - [](#) + - [Class-like tables and inheritance.](#class-like-tables-and-inheritance) ## The basics @@ -138,6 +138,13 @@ end x, y = bar('zaphod') --> prints "zaphod nil nil" -- Now x = 4, y = 8, values 15..42 are discarded. +print(type(x)) --> number +-- 'type()' function allow to detemindthe type of a variable. + +-- '...' is an elipse parameter, retrievable in context by '...'. +function e(...) print(...) end +e(2, 4, 8, 6) --> prints "2 4 8 6" + -- Functions are first-class, may be local/global. -- (global) These are the same: function f(x) return x * x end @@ -211,8 +218,68 @@ end #### Metatables and metamethods +````lua +-- A table can have a metatable that gives the table +-- operator-overloadish behavior. Later we'll see +-- how metatables support js-prototypey behavior. + +f1 = {a = 1, b = 2} -- Represents the fraction a/b. +f2 = {a = 2, b = 3} + +-- This would fail: +-- s = f1 + f2 + +metafraction = {} +function metafraction.__add(f1, f2) + sum = {} + sum.b = f1.b * f2.b + sum.a = f1.a * f2.b + f2.a * f1.b + return sum +end + +setmetatable(f1, metafraction) +setmetatable(f2, metafraction) + +s = f1 + f2 -- call __add(f1, f2) on f1's metatable + +-- f1, f2 have no key for their metatable, unlike +-- prototypes in js, so you must retrieve it as in +-- getmetatable(f1). The metatable is a normal table +-- with keys that Lua knows about, like __add. + +-- But the next line fails since s has no metatable: +-- t = s + s +-- Class-like patterns given in the section below would fix this. + +-- An __index on a metatable overloads dot lookups: +defaultFavs = {animal = 'gru', food = 'donuts'} +myFavs = {food = 'pizza'} +setmetatable(myFavs, {__index = defaultFavs}) +eatenBy = myFavs.animal -- works! thanks, metatable +-- Direct table lookups that fail will retry using +-- the metatable's __index value, and this recurses. + +-- An __index value can also be a function(tbl, key) +-- for more customized lookups. + +-- Values of __index, add, .. are called metamethods. +-- Main list. Here is a table with the metamethods. + +-- __add(a, b) for a + b +-- __sub(a, b) for a - b +-- __mul(a, b) for a * b +-- __div(a, b) for a / b +-- __mod(a, b) for a % b +-- __pow(a, b) for a ^ b +-- __unm(a) for -a +-- __concat(a, b) for a .. b +-- __len(a) for #a +-- __eq(a, b) for a == b +-- __lt(a, b) for a < b +-- __le(a, b) for a <= b +-- __index(a, b) for a.b +-- __newindex(a, b, c) for a.b = c +-- __call(a, ...) for a(...) ```` -```` - -#### \ No newline at end of file +#### Class-like tables and inheritance. \ No newline at end of file