Page 1 of 2
confused somewhat
Posted: Sun Jun 29, 2014 7:19 pm
by jasper.davis
so I recently decided to learn how to do classes in lua. I was trying to understand the code behind
loveTank alittle for fun. however, the most important document, class.lua, I wasn't understanding immediately. so I followed the
link provided to learn it. though I know how it works in some places, I get confused after "local mt = {}". could someone help me? I think there's a typo in there possibly.
Re: confused somewhat
Posted: Sun Jun 29, 2014 8:16 pm
by Ramcat
Code: Select all
-- expose a constructor which can be called by <classname>(<args>)
local mt = {}
mt.__call = function(class_tbl, ...)
I presume these are the lines of the class.lua file you are referring to? I spent all of yesterday reading the online version of
Programming in Lua which is the source reference for the
class.lua you are talking about.
Lua can use two tables to represent a class. The table and a
metatable that has been assigned to the table. This is one of the mechanisms that Lua uses to simulate inheritance.
The line, "local mt = {}" creates the metatable. The next line assigns a function to the
metamethod __call. What I find hard to understand about this is the metamethods are "magic", I haven't found much documentation on them other than the above links. There are a bunch of metamethods that are called on the metatable of the table that is the object.
Re: confused somewhat
Posted: Sun Jun 29, 2014 8:49 pm
by jasper.davis
I think I figured it out after alittle looking.
the segment looks like this on the page.
Code: Select all
local mt = {}
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj,c)
if init then
init(obj,...)
else
-- make sure that any stuff from the base class is initialized!
if base and base.init then
base.init(obj, ...)
end
end
return obj
end
however I think it's supposed to be indented, like so
Code: Select all
local mt = {}
mt.__call = function(class_tbl, ...)
local obj = {}
setmetatable(obj,c)
if init then
init(obj,...)
else
-- make sure that any stuff from the base class is initialized!
if base and base.init then
base.init(obj, ...)
end
end
return obj
end
After fixing this small issue, the code actually seems to make some sense. I could be wrong but it feels like it's a correct guess.
Re: confused somewhat
Posted: Sun Jun 29, 2014 8:51 pm
by jasper.davis
Ramcat wrote: I spent all of yesterday reading the online version of
Programming in Lua which is the source reference for the
class.lua you are talking about.
Lua can use two tables to represent a class. The table and a
metatable that has been assigned to the table. This is one of the mechanisms that Lua uses to simulate inheritance.
The line, "local mt = {}" creates the metatable. The next line assigns a function to the
metamethod __call. What I find hard to understand about this is the metamethods are "magic", I haven't found much documentation on them other than the above links. There are a bunch of metamethods that are called on the metatable of the table that is the object.
yeah I read through that part as well today.
Re: confused somewhat
Posted: Mon Jun 30, 2014 3:05 am
by ejmr
Ramcat wrote:What I find hard to understand about this is the metamethods are "magic", I haven't found much documentation on them other than the above links. There are a bunch of metamethods that are called on the metatable of the table that is the object.
It may help to think of metamethods as a way to support standard operators on your own data structures (i.e. tables). For example, if you represented matrices with tables then you could define ‘Matrix.__add()’ so that you could write code like ‘x + y’, where those two variables are Matrix tables. This lets you avoid writing code like ‘x:add(y)’, which I think many people would find cumbersome. I hope that makes some sense and helps.
Re: confused somewhat
Posted: Sun Jul 06, 2014 12:07 pm
by T-Bone
If you don't know much about metatables, then reading a class library can be a bit hard. If you just want to do really simple OO, I recommend using this "magic function"
Code: Select all
function inherit(a, b)
-- makes a inherit eveyrhting from b
b.__index = b
setmetatble(a,b)
return a
end
Then you really have everything you need; you create classes by just creating a table containing all the stuff you want every object of that class to have, and to instantiate you just create a new table and use the inherit function on it.
For example:
Code: Select all
awesomeclass = {}
awesomeclass.text = "default text"
function awesomeclass:print()
love.graphics.print(self.text, 10, 10)
end
local obj = inherit({}, awesomeclass)
obj.text = "another text"
obj:print() -- prints "another text", would've printed "default text" without the previous line
Re: confused somewhat
Posted: Sun Jul 06, 2014 7:37 pm
by OttoRobba
It can be a little bit confusing.
I generally prefer
closure OOP - which I honestly find a lot simpler to do and manage.
Lua-users has
a wiki page with explanations on the apporaches to Lua's oop.
Re: confused somewhat
Posted: Mon Jul 07, 2014 12:24 am
by murks
Metatables is a concept I try to grasp since quite some time, basically since I first encountered Lua, without success.
Maybe someone should write a "Metatables for dummies" book. This stuff is really confusing.
Re: confused somewhat
Posted: Mon Jul 07, 2014 1:57 am
by Inny
murks wrote:Metatables is a concept I try to grasp since quite some time, basically since I first encountered Lua, without success.
Maybe someone should write a "Metatables for dummies" book. This stuff is really confusing.
Metatables are really just another table that explains what Lua should do if it encounters a special situations. The most common situation is a missing key from a table. If a table doesn't have a value stored at a key you ask for, it checks the metatable for an explanation of what to do. Specifically, the __index key on that metatable. If __index is a function, it runs the function. If it's another table, it goes looking for the key in that table. And if that table is missing the key, you check it's metatable. So, the chain from an object, or a table with a metatable set, goes object[key] to getmetatable(object).__index[key] to getmetatable(getmetatable(object).__index).__index[key].
Now, sometimes you see this
All that is saying is that this table (which will be a metatable) uses itself as its own __index metamethod.
Re: confused somewhat
Posted: Mon Jul 07, 2014 11:31 am
by Robin
Metatables are not complicated. They are very simple. You don't need a book to explain them, a
chapter is enough.
The thing is, to understand metatables, something has to "click" in your head (like many other concepts in fields like programming and maths), and that's a very personal thing. We can try to explain metatables to you, like Inny did, but we can't know what the thing will be that makes
you have that click. Maybe the best thing would be for you to keep trying to use them, even if you don't understand what you're doing and listening to our explanations until you get your click.