A little help with metatables?

RedTalonRedTalon Join Date: 2012-11-14 Member: 171203Members
Ok, firstly I'm bad at learning abstract concepts; unless I see how they work or someone carefully explain how things fit in I almost never understand. So, what I can recall from tutorials are that metatables are something like a substitution for objects or classes. I still don't understand what they're really meant for. I also have something that confuses me.
button = {}
button.__index = button

function button.create(txt,fnt,x,y)	
	local temp = {}
	setmetatable(temp,button)
	temp.hover = false
	temp.click = false
	temp.text = txt
	temp.font = fnt
	temp.width = fnt:getWidth(txt)
	temp.height = fnt:getHeight()
	temp.x = x
	temp.y = y
	return temp	
end

function button:mousepressed(x,y,b)
	blablablabla
end

This is a rough example of my problem (its a modified code from a snipit). Anyway, I'm thinking the table <button> is the so called class... or is it <temp>? Also I need to understand the FUNCTIONAL difference between the < . > and < : >; i.e. difference between <button.create(txt,fnt,x,y)> and <button:mousepressed(x,y,b)>.

Can someone please help me with this? If I were to get around this I might get the hang of lua and actually make something more than some kind of list organiser or number cruncher.

Comments

  • RioRio Join Date: 2005-01-28 Member: 38716Members
    edited February 2013
    Metatables are an extension to tables, which lets you add custom code to operators like when you add a new element to your table or when you access an element by its index (like in your example).
    I wouldn't compare tables and classes, because in my opinion, they are not the same thing. However, both have attributes and functions.
    Here's a quick example:
    test = {}
    testMetaTable = {}
    testMetaTable.__index = function(table, index)
        if (table[index]) then
            Print("yay, someone accessed index " .. index .. " and it does exist!")
            return test[index]
        else        
            Print("oh no! we don't have index " .. index .. " :(")
            return "INDEX NOT FOUND!"
        end
    end
    setmetatable(test, testMetaTable)
    
    Print(test.yay) // Prints 'oh no! we don't have index yay :(' and 'INDEX NOT FOUND!'
    
    test.yay = "blub" 
    Print(test.yay) // Prints 'yay, someone accessed index yay and it does exist!' and 'blub'
    
    If you need another examples, here is one.


    Regarding your second question, the difference between calling a function by period and by colon is that calling by period is called a function call and calling by colon is called a method call. Let me answer this with a code example:
    test = {}
    test.fancyAttribute = "I like trains!"
    
    function test.GetFancyAttributeByFunction(table)
        // self.fancyAttribute would return nil
        return table.fancyAttribute
    end
    
    function test:GetFancyAttributeByMethod()
        return self.fancyAttribute
    end
    
    function test:GetFancyAttribute()
        return self.GetFancyAttribute(self)
    end
    
    GetFancyAttributeByFunction will always be a function and therefore requires the table on which to get the variable called fancyAttribute.
    If you call GetFancyAttributeByMethod, you can use 'self' to access the current table (in this case it's test) to access the attribute directly.

    A function doesn't know if it's part of a table, but a method does know that it's part of a table and therefore you can use the 'self' keyword.
    In some examples you will see, that people name their parameter 'self' (instead of 'table', like in the example above), so they have the same behavior.

    There's a good example on this one here.
  • RedTalonRedTalon Join Date: 2012-11-14 Member: 171203Members
    Ah thanks a lot. I think I've got some of the concepts nailed. I'll keep reading the programming guide you linked and hopefully with a lot of testing and trial & error I'll get the hang of it.
  • RedTalonRedTalon Join Date: 2012-11-14 Member: 171203Members
    edited February 2013
    Sorry for bumping post.

    If I were to create an array of instances of a class how would I go about doing that? Do I create a table?

    For example <Gun> is a 'class' (I understand in lua terms its a 'prototype'). <C-14> is an object (or instance) of <Gun>. If I want to create multiple <C-14> and manage individually positions, states, etc... , do I store it in an indexed table? Or is there some kind of special trick to this?
Sign In or Register to comment.