|
You last visited: Today at 00:18
Advertisement
[Guide] Lua Allgemeines, Metatables, Metamethods (fortgeschrittener Guide)
Discussion on [Guide] Lua Allgemeines, Metatables, Metamethods (fortgeschrittener Guide) within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.
11/07/2015, 18:22
|
#1
|
elite*gold: 83
Join Date: Nov 2013
Posts: 2,891
Received Thanks: 2,764
|
[Guide] Lua Allgemeines, Metatables, Metamethods (fortgeschrittener Guide)
Dieser Guide richtet sich an diejenigen, die bereits Erfahrung im Coding mit Lua haben. Grundkenntnisse über Lua werden vorausgesetzt.
Allgemeines:
Der global Table:Der global Table enthält alle globalen Variablen. Der global Table ist über die Variable _G verfügbar. Wird eine neue globale Variable gesetzt, wird diese in den global Table geschrieben.
Mit dieser Info können wir z.B. auf globale Variablen zugreifen, dessen Name lokal genutzt wird.
Beispiel:
Code:
name = "Sensi"
local name = "Faggot: Akkelos"
print(name)--immer lokale VOR globalen Variablen (in diesem Fall also -> "Faggot: Akkelos")
print(_G.name)--über den global Table -> "Sensi"
Ausserdem ist es über den global Table möglich, globale Variablen zu setzen, auch wenn lokal eine Variable mit gleichem Namen zugreifbar ist:
Code:
local name = "Sensi"
name = "Faggot: Akkelos"--überschreibt die lokale Variable "name", weil sie an dieser Stelle zugreifbar ist
_G.name = "Faggot: Akkelos"--setzen der globalen Variable per global Table
Metatables:
Was sind Metatables?:Metatables sind Tables, die Grundfunktionen eines Tables (z.B. das Verhalten beim Aufruf der tostring() Funktion) enthalten.
Mit der Funktion getmetatable(<table>) bekommt man den Metatable eines Tables zurück, mit setmetatable(<table>, <table>) setzt man diesen. Metamethods:
Was sind Metamethods?:Metamethods sind die Funktionen, die im Metatable liegen, um das Verhalten des Tables bei bestimmten Operationen zu definieren.
Es sind verschiedenste Sachen über Metatables / Metamethods möglich, z.B. die Erstellung eines Tables, aus dem nur gelesen werden darf (read-only-table) oder read-only-values (Werte, die nach ihrer Deklaration nur gelesen werden dürfen) Welche Metamethods gibt es?:| Funktionsname | Wird aufgerufen, wenn ... | Parameter | Rückgabe | Sonstiges |
|---|
| __index | ... versucht wird, auf einen undefinierten Key zuzugreifen | #1: Table, auf den zugegriffen wurde #2: Angefragter Key | Der Wert, der zurückgegeben werden soll (Standard: nil) | #1: Anstatt einer Funktion kann hier auch ein anderer Table hinterlegt werden. #2: Kann durch rawget(<table>, <key>) ignoriert werden | | __newindex | ... ein neuer Key auf den Table gesetzt wird | #1: Table, auf den der Key gesetzt werden soll #2: Zu setzender Key | (Keine) | #1: Kann durch rawset(<table>, <key>, <value>) ignoriert werden | | __mode | ... ein neuer Key auf den Table gesetzt wird | (Keine) - Stringwert "k", "v" oder "kv" der besagt, ob die Referenzen auf dem Table relevant für den Garbagecollector sind. | (Keine (weil keine Funktion)) | - | | __call | ... der Table als Funktion genutzt wird | #1: Table, der als Funktion genutzt wurde #...: Übergebene Parameter | was auch immer gewollt ist | - | | __metatable | ... getmetatable(<table>) aufgerufen wird | (Keine) | Wert, der zurückgegeben werden soll, wenn getmetatable(<table>) aufgerufen wird | - | | __tostring | ... tostring(<table>) aufgerufen wird | #1: Der Table, der an tostring(<table>) übergeben wurde | Der resultierende String | - | | __len | ... table.getn(<table>) aufgerufen wird | #1: Der Table, der an table.getn(<table>) übergeben wurde | Die resultierende Länge | - | | __gc | ... der Garbagecollector den Table löschen möchte | #1: Der Table, der gelöscht werden soll | (Keine) | - | | __unm | ... der negative Wert (-<table>) angefordert wird | #1: Der Table, für den der negative Wert angefordert wird | Das Ergebnis | - | | __add | ... eine Addition mit dem Table ausgeführt werden soll | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | Das Ergebnis der Addition (Operator1 + Operator2!) | Beispiel: <table> + 1 -> Operator1 = <table>, Operator2 = 1 bzw.: 1 + <table> -> Operator1 = 1, Operator2 = <table> | | __sub | ... eine Subtraktion mit dem Table ausgeführt werden soll | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | Das Ergebnis der Subtraktion (Operator1 - Operator2!) | - | | __mul | ... eine Multiplikation mit dem Table ausgeführt werden soll | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | Das Ergebnis der Multiplikation (Operator1 * Operator2!) | - | | __div | ... eine Division mit dem Table ausgeführt werden soll | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | Das Ergebnis der Division (Operator1 / Operator2!) | - | | __mod | (nicht in Lua 5.0) | - | - | - | | __pow | ... eine Potenz des Tables angefordert wird | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | Das Ergebnis (Operator1 ^ Operator2!) | - | | __concat | ... der Table konkateniert wird | #1: Wert1, #2: Wert2 | Der einzufügende String bei einer Konkatenation (Empfohlen: tostring(v1) .. tostring(v2)) | - | | __eq | ... Prüfung auf gleichheit (Achtung! Nur wenn beide Operatoren die selbe (nicht nur Inhaltlich) Funktion unter __eq hinterlegt haben) | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | true oder false | - | | __lt | ... Prüfung auf größer / kleiner | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | true oder false | - | | __le | ... Prüfung auf gröper / kleiner oder gleich | #1: Operator1 (Achtung! Nicht zwingend "dieser Table"), #2: Operator2 | true oder false | - |
Beispiele:
__index
Code:
local meta = {
__index = function(tbl, key)
return key
end
}
local names = {sensi = "Felix", akkelos = "Laurin"}
setmetatable(names, meta)
print(names.sensi)
print(names.akkelos)
print(names.yiv)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
Felix
Laurin
yiv
>
Alternativ: Hinterlegen eines Tables:
Code:
local names2 = {yiv = "Faggot#2"}
local meta = {
__index = names2
}
local names = {sensi = "Felix", akkelos = "Laurin"}
setmetatable(names, meta)
print(names.sensi)
print(names.akkelos)
print(names.yiv)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
Felix
Laurin
Faggot#2
>
__newindex
Code:
local meta = {
__newindex = function(tbl, key, value)
print(string.format("creating new index (%s) on %s: %s", tostring(key), tostring(tbl), tostring(value)))
end
}
local names = {sensi = "Felix", akkelos = "Laurin"}
setmetatable(names, meta)
names.yiv = "Faggot#2"
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
creating new index (yiv) on table: 00000000007E14F0: Faggot#2
>
__mode
Code:
local meta = {
__mode = "v"
}
local names = {}
setmetatable(names, meta)
if true then
local x = {}
names[1] = x
end
collectgarbage()
print(names[1])
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
nil
>
__call
Code:
local meta = {
__call = function(tbl, ...)
for k,v in ipairs(arg) do
table.insert(tbl, v)
end
end
}
local names = {}
setmetatable(names, meta)
names("Felix", "Laurin", "Faggot#2")
for k,v in ipairs(names) do
print(v)
end
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
Felix
Laurin
Faggot#2
>
__metatable
Code:
local meta = {
__metatable = "xd",
}
local names = {}
setmetatable(names, meta)
print(getmetatable(names))
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
xd
>
__tostring
Code:
local meta = {
__tostring = function(tbl)
local str = ""
for k,v in ipairs(tbl) do
str = str .. (str == "" and "" or ", ") .. v
end
return "{" .. str .. "}"
end
}
local names = {"Felix", "Laurin"}
setmetatable(names, meta)
print(names)--tostring wird hier automatisch aufgerufen
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
{Felix, Laurin}
>
__len (nicht in Lua 5.0)
Code:
local meta = {
__len = function(tbl)
local length = 0
for k,v in ipairs(tbl) do
length = length + string.len(tostring(v))
end
return length
end
}
local names = {"Felix", "Laurin"}
setmetatable(names, meta)
print(#names)
Code:
Lua 5.5.1 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
11
>
__gc (nicht in Lua 5.0)
Code:
if true then
local meta = {
__gc = function(tbl)
_G.__BACKUP__ = {}
for k,v in ipairs(tbl) do
table.insert(_G.__BACKUP__, v)
end
end
}
local names = {"Felix", "Laurin"}
setmetatable(names, meta)
end
collectgarbage()
for k,v in ipairs(_G.__BACKUP__) do
print(v)
end
Code:
Lua 5.5.1 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
Felix
Laurin
>
__unm
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__unm = function(tbl)
return -(tbl + 0)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(-tbl)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
-31
>
__add
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(tbl + 10)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
41
>
__sub
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__sub = function(operand1, operand2)
return (operand1 + 0) - (operand2 + 0)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(tbl - 10)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
21
>
__mul
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__mul = function(operand1, operand2)
return (operand1 + 0) * (operand2 + 0)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(tbl * 10)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
310
>
__div
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__div = function(operand1, operand2)
return (operand1 + 0) / (operand2 + 0)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(tbl / 10)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
3.1
>
__pow
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__pow = function(operand1, operand2)
return (operand1 + 0) ^ (operand2 + 0)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print(tbl ^ 10)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
8.196282869808e+014
>
__concat
Code:
local meta = {
__tostring = function(tbl)
local str = ""
for k,v in ipairs(tbl) do
str = str .. (str == "" and "" or ", ") .. v
end
return "{" .. str .. "}"
end,
__concat = function(str1, str2)
return tostring(str1) .. tostring(str2)
end
}
local tbl = {1, 10, 20}
setmetatable(tbl, meta)
print("tbl: " .. tbl)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
tbl: {1, 10, 20}
>
__eq
Code:
local meta = {
__eq = function(operand1, operand2)
for i = 1, table.getn(operand1) do
if operand1[i] ~= operand2[i] then
return false
end
end
return true
end,
}
local tbl1 = {1, 10, 20}
local tbl2 = {1, 10, 20}
local tbl3 = {1, 10}
setmetatable(tbl1, meta)
setmetatable(tbl2, meta)
setmetatable(tbl3, meta)
print(tbl1 == tbl2)
print(tbl1 == tbl3)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
true
false
>
__lt
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__lt = function(operand1, operand2)
return (operand1 + 0) < (operand2 + 0)
end,
}
local tbl1 = {1, 10, 20}
local tbl2 = {1, 10, 20}
local tbl3 = {1, 10}
setmetatable(tbl1, meta)
setmetatable(tbl2, meta)
setmetatable(tbl3, meta)
print(tbl1 > tbl2)
print(tbl1 > tbl3)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
false
true
>
__le
Code:
function sum(tbl)
local value = 0
for k,v in ipairs(tbl) do
value = value + v
end
return value
end
local meta = {
__indentifier = "META#2840214702",
__add = function(operand1, operand2)
local o1meta = getmetatable(operand1) or {}
local o2meta = getmetatable(operand2) or {}
if o1meta.__indentifier and o1meta.__indentifier == "META#2840214702" then
operand1 = sum(operand1)
end
if o2meta.__indentifier and o2meta.__indentifier == "META#2840214702" then
operand2 = sum(operand2)
end
return operand1 + operand2
end,
__le = function(operand1, operand2)
return (operand1 + 0) <= (operand2 + 0)
end,
}
local tbl1 = {1, 10, 20}
local tbl2 = {1, 10, 20}
local tbl3 = {1, 10}
setmetatable(tbl1, meta)
setmetatable(tbl2, meta)
setmetatable(tbl3, meta)
print(tbl1 >= tbl2)
print(tbl1 >= tbl3)
Code:
Lua 5.0.3 Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> dofile("test2.lua")
true
true
>
read-only-value
Code:
local READONLY = {}
_G.__READONLY__ = setmetatable({}, {
__index = READONLY,
__newindex = function(tbl, key, value)
if READONLY[key] ~= nil then
error("attempt to modify read-only value")
return
end
READONLY[key] = value
end,
__metatable = false
})
function readOnlyValue(name, value)
_G.__READONLY__[name] = value
end
local _GmetaRef = getmetatable(_G) or {}
_GmetaRef.__index = function(tbl, key)
return tbl.__READONLY__[key]
end
_GmetaRef.__newindex = function(tbl, key, value)
if tbl.__READONLY__[key] ~= nil then
error("attempt to modify read-only value")
return
end
rawset(tbl, key, value)
end
setmetatable(_G, _GmetaRef)
readOnlyValue("test", "Hello World!")
print(test)
test1 = "x"
test = "x"
|
|
|
11/07/2015, 18:23
|
#2
|
elite*gold: 47
Join Date: Feb 2012
Posts: 2,282
Received Thanks: 2,579
|
Manchmal frage ich mich, warum hast du so viel Zeit und ich nicht? 
Danke dafür, aber brauche ich zur Zeit nicht, kann dich ja für Lua knechten
MfG
|
|
|
11/07/2015, 18:23
|
#3
|
elite*gold: 0
Join Date: Jun 2013
Posts: 1,217
Received Thanks: 328
|
gj
|
|
|
11/07/2015, 18:25
|
#4
|
elite*gold: 2785
Join Date: Dec 2014
Posts: 403
Received Thanks: 1,354
|
Sehr übersichtlich gestaltet. Danke für das Release
|
|
|
11/07/2015, 18:25
|
#5
|
elite*gold: 0
Join Date: Feb 2015
Posts: 306
Received Thanks: 171
|
krass.... das ist der Sensi eben 
hast du schöne gemacht
schöne grüße
Kampfzwerg
|
|
|
11/07/2015, 18:38
|
#6
|
elite*gold: 26
Join Date: Sep 2014
Posts: 895
Received Thanks: 388
|
So viel Zeit für solche Dinge möchte ich auch mal haben
Sehr übersichtlich und verständlich geschrieben. Wird vielen ein wenig Hilfestellung sein. Danke für die Mühe!
|
|
|
11/07/2015, 23:46
|
#7
|
elite*gold: 35
Join Date: Apr 2014
Posts: 992
Received Thanks: 1,647
|
Hab zwar keine Ahnung was das ist, aber weil du dir so viel Mühe gegeben hast und wir gerade im Ts sind, bekommst du trotzdem n Thanks
PS: Fix dein BO3
Mfg.
|
|
|
11/08/2015, 01:20
|
#8
|
elite*gold: 0
Join Date: Nov 2013
Posts: 22
Received Thanks: 20
|
hast dir viel mühe gegeben thx
|
|
|
11/08/2015, 02:38
|
#9
|
elite*gold: 1810
Join Date: Jan 2012
Posts: 2,208
Received Thanks: 1,630
|
Oha hast dir ja richtig viel Mühe gegeben, da wird dann Lua doch wieder erheblicher *_*
Thanks 4 release
|
|
|
 |
Similar Threads
|
[GUIDE] Für Anfänger / Neueinsteiger Allgemeines
01/11/2013 - Metin2 Guides & Templates - 8 Replies
Hallo liebe Epvp-Freunde,
ich weis es gibt schon einige Threads aber hier geht es um das EInsteigen wie alles funktioniert / etc.
vorab : Rechtschreibfehler / Grammatikfehler tun mir jetzt schon mal leid, ich bin nicht der ebste dadrin.
-> Ich hatte schonmal so ein Guide im de-Forum also kann es dem auch ähneln :D
Hier mal eine kleine Gliederung :
1. Der Einstieg -> Charakter Auswahl / Reiche
|
[Guide]Farm Guide Metin2[Guide]
02/05/2012 - Metin2 Guides & Templates - 24 Replies
#Delet aus sicherheits gründen.
|
[GUIDE] Item Filter Guide | Cabal Crafting & Dungeon Guide by Dewa Gempak.
06/15/2008 - Cabal Guides & Templates - 5 Replies
Since its his work, just SHARING it here, i just gonna link his URL from his work. because i dont like copy and pasting other ppl's guides:
http://119.110.98.150:90/ipb/index.php?showtopic= 1145
Q#1: Does it work with CabalRider (PH)?
A#1: Yes, it works, i tried it personally myself.
Q#2: I'm too dumb to understand it, how to make it work.
A#2: Try reading it again and again, if u still don't know how, don't use it then sleep.gif
|
All times are GMT +1. The time now is 00:25.
|
|