Lua Logo
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
nach obenNoch lange nicht fertig.
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