This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Kouksi44's profile picture

OOP in LUA metatabes concept problem

Started by Kouksi44, 14 August 2014 - 10:33 PM
Kouksi44 #1
Posted 15 August 2014 - 12:33 AM
Hi,

so I came across the concept of OOP in Lua and now I am really trying to get into this topic.
One of my problems in understanding is, the function of metatables.

The author of One of the tutorials says:
(http://www.computercraft.info/forums2/index.php?/topic/8393-oop-in-lua/)

"When we call this function, we can either call Person.getName(personObject) or personObject:getName(). Notice the colon instead of full-stop in the second call. This tells Lua to find the getName function in Person_mt.__index and pass personObject as the first parameter."

So does this mean, that the metatables are only used, so that you can use ":" instead of "." and you can leave out the self statement ?

Im pretty new to this realisation of the oop concept in lua so it would be nice to answer me in a very simple way ! :)/>

Thank you in advance

Kouksi44
Lyqyd #2
Posted 15 August 2014 - 01:04 AM
Nope.

Ignore the metatables part for now. The colon syntax for calling methods out of a table is just syntactic sugar. These two are equivalent:


t.func(t)

t:func()

All the colon means is, "send the table containing the function as the first argument of the function".

Now, separately, what metatables allow you to do with the colon notation is use one function for all of your tables. So you have a base table of functions. You use the __index metamethod of several tables to all point to the base table. So if you called this:


instance:func()

The instance table doesn't actually contain the func function, the func function is actually in our base table of functions. But the table you used to call it is still passed to the function, rather than the table the function is *actually* in. So that line of code is equivalent to this:


base.func(instance)

Which is useful, instead of this, which would be useless:


base.func(base)

There are two separate concepts at work there. If that still doesn't clear it up, please ask some more questions about it!
natedogith1 #3
Posted 15 August 2014 - 01:08 AM
metatables are also used for overriding operators (like '+','-','*',etc). If you're looking into a bit more info on metatables specifically, I'd recommend looking at this.
Bomb Bloke #4
Posted 15 August 2014 - 05:26 AM
There's another way of doing something similar to what Lyqyd describes without using metatables at all.

The idea is that when you generate your new "object", you create a table to represent it, and you also create another table to hold data specific to it. Then you manually dump fresh new instances of all the functions you want into the object table, and these in turn reference the data table (which, once the object is returned, will only be accessible via those functions). Like this:

function newObject()
	local myNewObject = {}
	local objectData = {}
	
	function myNewObject.setFuncData1(par)
		objectData.func1Data = par
	end
	
	function myNewObject.getFuncData1()
		return objectData.func1Data
	end
	
	function myNewObject.setFuncData2(par)
		objectData.func2Data = par
	end
	
	function myNewObject.getFuncData2()
		return objectData.func2Data
	end
	
	-- etc
	
	return myNewObject
end

You can then do stuff like this:

local moo1, moo2 = newObject(), newObject()

moo1.setFuncData1("hello")
moo2.setFuncData1("world")

print(moo1.getFuncData1().." "..moo2.getFuncData1())

This allows you to use a dot instead of a colon to call your object's functions, while also leaving out the "self"-reference.

The downside is that it's a waste of memory - metatables allow you to make one copy of all your functions available to many "objects", whereas this method forces you to generate duplicate copies of those functions. The pros don't outweigh the cons, to my mind, though this is the technique used by CC 1.6's "window" API and I feel it's worth mentioning.
Kouksi44 #5
Posted 15 August 2014 - 02:30 PM
Wow, thats a lot of Information !
But thank you a lot i got it now !

So if i create a table called Person (i know just like the tutorial)

And I define some functions inside of this base table and then finally create another table inside of this table and add the base table as the metatable of this subtable, the subtable can access all the functions of the base table.

Thank you a lot this topic is really fascinating for me ! :)/>
Lyqyd #6
Posted 15 August 2014 - 03:29 PM
You would probably not want to create them as subtables of the Person table, but other than that, you have it correct.