Metatables
Wie wir bis jetzt schon wissen sollten, kann man mit tables einige Sachen nicht ohne weiteres machen.
Metatables geben uns aber die Möglichkeit einem Table Anweisungen zu geben, was bei einem ansonsten nicht erlaubten Zugriff auf ein table geschehen soll.
Jedes table oder userdata object in Lua kann ein Metatable haben.
Beispiele für nicht erlaubte Zugriffe:
- + addieren
- - subtrahieren
- * multiplizieren
- etc.
Wie macht lua das?
Es wird einfach ein table erzeugt, in dem Funktionen liegen, die im Falle einer solchen Handlung aufgerufen werden.
Wird eine Addition mit tables versucht, so sucht lua nach einer Funktion __add in diesem table. Ist diese Funktion vorhanden, so wird sie ausgeführt.
Dazu müssen wir aber das table zunächst machen und dann dem anderen table zuweisen.
Erzeugen des Funktionstables:
metaT={} -- ein Table ist geboren
metaT.__add = function( table1, table2 )
-- jetzt kommen hier alle Anweisungen hinein,
-- die im Falle einer Addition von tables
-- durchgeführt werden sollen.
end
Natürlich können wir auch gleichzeitig für andere Handlungen eine Funktion zuweisen:
metaT.__sub = function( table1, table2 )
-- jetzt kommen hier alle Anweisungen hinein,
-- die im Falle einer Subtraktition von tables
-- durchgeführt werden sollen.
end
metaT.__mul = function( table1, table2 )
-- jetzt kommen hier alle Anweisungen hinein,
-- die im Falle einer Multiplikation von tables
-- durchgeführt werden sollen.
end
und so weiter. Die Liste der Möglichkeiten ist umfangreich. Wichtig ist zunächst zu wissen, wie man eine Funktion für eine bestimmte Handlung erstellt.
jetzt müssen wir noch dem table das Metatable zuweisen.
Dies geschieht einfach mit:
setmetatable(meinTable, metaT)
Was in den Funktionen steht, ist vollkommen uns überlassen. Wichtig ist nur der Rückgabewert.
Nehmen wir einmal an, wir wollen zu einer Position in X-Richtung 100 addieren und in Y-Richtung 500
pos = { X = 1205, Y = 5241 }
diff = { X = 100, Y = 500 } -- unsere Differenz
Würden wir jetzt schreiben:
ergebnis = pos + diff
Dann hätten wir einen dicken Fehler.(attempt to perform arithmetic on global `pos' (a table value) )
Machen wir also ein Metatable
metaT={} -- ein Table ist geboren
metaT.__add = function( table1, table2 )
local table3 = {}
table3.X = table1.X + table2.X
table3.Y = table1.Y + table2.Y
return table3
end
setmetatable(pos, metaT)
ergebnis = pos + diff
Das geht natürlich wesendlich einfacher ist aber nicht so übersichtlich:
metaT={} -- ein Table ist geboren
metaT.__add = function( table1, table2 )
return {X = table1.X + table2.X, Y = table1.Y + table2.Y }
end
setmetatable(pos, metaT)
ergebnis = pos + diff
Dann lassen wir uns das Ergebnis ausdrucken:

Das ganze geht auch anders herum: ergebnis = diff + pos
Für diff können wir auch alles mögliche einsetzten (Zahlen, Strings,...). Die Funktion muss das nur verkraften können.
Funktion | Anwendungsfall (wird aufgerufen wenn:) |
---|---|
__add | Addition |
__sub | Subtraktion |
__mul | Multiplication |
__div | Division |
__pow | Potenzierung |
__unm | Wenn ein table mit dem unären Operator - versehen wird |
__concat | Wenn zwei tables mit .. verknüpft werden |
__eq | zwei tables werden mit == verglichen |
__it | zwei tables werden mit < verglichen |
__le | zwei tables werden mit <= verglichen |
__index | Es wurde ein Wert aufgerufen, den es in dem table nicht gibt. |
__newindex | Wenn ein table ein neues Element bekommt. Z.B x und y sind vorhanden, z wird definiert. |
__call | Wenn irgendein Wert im table angesprochen wird |
__mode | |
__metatable | |
__tostring | Wenn die Funktion tostring auf ein table angewendet wird |
__gc |
Die Vervielfältigung der auf diesen Seiten enthaltenen Informationen und Grafiken ist untersagt, ausgenommen davon ist sämtlicher auf diesen Seiten angezeigter Quellcode.
Siehe auch: Haftungsausschluss
Copyright © Robert Schmitz 2006
Siehe auch: Haftungsausschluss
Copyright © Robert Schmitz 2006