1. Post #1
    LuaGuy's Avatar
    April 2011
    129 Posts
    I have 3 question about Lua. I have read and watched dozens of tutorials but still cant understand these 3 things.

    What is Metatable?
    What is Metamethod?
    And i always see, this piece of code "blah:blah", ignore the quotes. What is the mean of the colon between one thing and another thing?

    Please dont give me tutorial link's cause i already read every Lua tutorial on the web. But still cant understand 3 things as i mentioned above. So please explain yourself. Especially the weird colon.

    (User was banned for this post ("Wrong section" - mahalis))

  2. Post #2
    Gold Member
    Treelor's Avatar
    February 2005
    2,080 Posts
    In my limited experience with lua, the colon represents the separation between an entity and a command operating on that entity.
    Reply With Quote Edit / Delete Reply Windows 7 Show Events Agree Agree x 1 (list)

  3. Post #3
    LuaGuy's Avatar
    April 2011
    129 Posts
    In my limited experience with lua, the colon represents the separation between an entity and a command operating on that entity.
    I heard it is called constructor. But what is a constructor ? What is the function of that colon ? Why we have to put that colon ?

  4. Post #4
    Please waste more of your money changing this title again.
    Gmod4ever's Avatar
    August 2005
    6,840 Posts
    Metatables, metamethods, and the colon syntax are all inter-related. Allow me to quickly explain their relationships.

    Let's say you have some entity. This entity is called Object. And on this entity, Object, you store a function that will color it pink. Such a function would look like this.

    Code:
    function Object.ColorMePink(myself)
    	myself:SetColor(255,255,0,255)
    end
    Now, as you go along, you realize that it becomes a bit tiredsome to do Object.ColorMePink(Object) all the time. You think to yourself "Well, this function is stored on Object, and I only ever use it to affect Object. It'd be a lot quicker if I could just call Object.ColorMePink(), and, since it's stored on Object, it'll automatically assume that I mean to do Object.ColorMePink(Object).

    And thusly, you add the colon syntax. Now instead of having to do Object.ColorMePink(Object) every time you want to color Object pink, you can now simply do Object:ColorMePink().

    Put another way, Object.ColorMePink(Object) and Object:ColorMePink() do the exact same thing.

    By extension, you can inter-related library.function and library:function syntax in such a way, regardless of the library or function, as shown by the relationship below.

    Code:
    -- This function
    function library.SomeFunction(self)
      DoSomething(self)
    end
    
    -- Is the same as this function
    function library:SomeFunction()
      DoSomething(self)
    end
    When you use metamethods by using ":", you are effectively calling that same function using ".", but Lua automatically throws in a first argument to that function. This argument is assigned the variable of "self," and will always refer to the entity that is calling it.

    By extension, with this function:
    Code:
    function Object.SomeFunction(self)
      DoSomething(self)
    end
    These operate exactly the same in calling it:

    Code:
    Code:
    Object.SomeFunction(Object)
    Object:SomeFunction()
    And it works with functions with more than one argument. With this function:
    Code:
    function Object.SomeFunction(self,a,b,c)
    	DoSomething(a,b,c)
    end
    You can do either of these methods: Object.SomeFunction(Object,1,2,3) or Object:SomeFunction(1,2,3). They are, on an engine level, identical.

    Much like you can call these functions interchangeably, so can you define them. These are all proper ways to define a function, and all three are identical in operation:

    Code:
    Object.SomeFunction = function(self,a,b,c)
    	DoSomething(self,a,b,c)
    end
    
    function Object.SomeFunction(self,a,b,c)
    	DoSomething(self,a,b,c)
    end
    
    function Object:SomeFunction(a,b,c)
    	DoSomething(self,a,b,c)
    end
    So effectively, metatables, metamethods, and the colon operator are all inter-related, and are simply a convenience method. Metatables and metamethods also extend into the fact that GLua is largely an Object-Oriented Language (an OOL), as opposed to a Non-OOL.

    I hope this cleared some things up.
    Reply With Quote Edit / Delete Reply Windows 7 United States Show Events Lua Helper x 3Friendly x 2Lua King x 2Agree x 1Informative x 1Useful x 1 (list)

  5. Post #5
    LuaGuy's Avatar
    April 2011
    129 Posts
    Metatables, metamethods, and the colon syntax are all inter-related. Allow me to quickly explain their relationships.

    Let's say you have some entity. This entity is called Object. And on this entity, Object, you store a function that will color it pink. Such a function would look like this.

    Code:
    function Object.ColorMePink(myself)
    	myself:SetColor(255,255,0,255)
    end
    Now, as you go along, you realize that it becomes a bit tiredsome to do Object.ColorMePink(Object) all the time. You think to yourself "Well, this function is stored on Object, and I only ever use it to affect Object. It'd be a lot quicker if I could just call Object.ColorMePink(), and, since it's stored on Object, it'll automatically assume that I mean to do Object.ColorMePink(Object).

    And thusly, you add the colon syntax. Now instead of having to do Object.ColorMePink(Object) every time you want to color Object pink, you can now simply do Object:ColorMePink().

    Put another way, Object.ColorMePink(Object) and Object:ColorMePink() do the exact same thing.

    By extension, you can inter-related library.function and library:function syntax in such a way, regardless of the library or function, as shown by the relationship below.

    Code:
    -- This function
    function library.SomeFunction(self)
      DoSomething(self)
    end
    
    -- Is the same as this function
    function library:SomeFunction()
      DoSomething(self)
    end
    When you use metamethods by using ":", you are effectively calling that same function using ".", but Lua automatically throws in a first argument to that function. This argument is assigned the variable of "self," and will always refer to the entity that is calling it.

    By extension, with this function:
    Code:
    function Object.SomeFunction(self)
      DoSomething(self)
    end
    These operate exactly the same in calling it:

    Code:
    Code:
    Object.SomeFunction(Object)
    Object:SomeFunction()
    And it works with functions with more than one argument. With this function:
    Code:
    function Object.SomeFunction(self,a,b,c)
    	DoSomething(a,b,c)
    end
    You can do either of these methods: Object.SomeFunction(Object,1,2,3) or Object:SomeFunction(1,2,3). They are, on an engine level, identical.

    Much like you can call these functions interchangeably, so can you define them. These are all proper ways to define a function, and all three are identical in operation:

    Code:
    Object.SomeFunction = function(self,a,b,c)
    	DoSomething(self,a,b,c)
    end
    
    function Object.SomeFunction(self,a,b,c)
    	DoSomething(self,a,b,c)
    end
    
    function Object:SomeFunction(a,b,c)
    	DoSomething(self,a,b,c)
    end
    So effectively, metatables, metamethods, and the colon operator are all inter-related, and are simply a convenience method. Metatables and metamethods also extend into the fact that GLua is largely an Object-Oriented Language (an OOL), as opposed to a Non-OOL.

    I hope this cleared some things up.
    This is mind blowing but very satisfactory explanation. So i dont have to use colon ? It is just an alternative way ? Thanks anyway.

  6. Post #6
    Steins;Gate SUCKS
    Dave_Parker's Avatar
    October 2008
    5,063 Posts
    This is mind blowing but very satisfactory explanation. So i dont have to use colon ? It is just an alternative way ? Thanks anyway.
    The colon, in it's simplest explanation, simply signifies that you want to pass the object as the first argument.

    So as Gmod4Ever stated, you can do
    Object.Function(Object, 1, 2, 3) -or-
    Object:Function(1, 2, 3)
    Reply With Quote Edit / Delete Reply Windows 7 Netherlands Show Events Lua Helper Lua Helper x 1 (list)

  7. Post #7
    LuaGuy's Avatar
    April 2011
    129 Posts
    The colon, in it's simplest explanation, simply signifies that you want to pass the object as the first argument.

    So as Gmod4Ever stated, you can do
    Object.Function(Object, 1, 2, 3) -or-
    Object:Function(1, 2, 3)
    Now i understand the colon. Thank you Dave_Parker and Gmod4ever. But still dont know what metatable and metamethod is ? I know the syntax but dont know the task ? Why they are exist and useful ?

  8. Post #8
    aurum481's Avatar
    November 2008
    2,522 Posts
    I think you can get a metatable of certain objects/entities.
    function _R.GetMetatable(Player).ColorGreen(self)
    self:SetColor(0, 200, 0, 255)
    end
    fix me if im wrong
    so now you can call on Player entity like ply:ColorGreen()
    Reply With Quote Edit / Delete Reply Lithuania Show Events Lua Helper Lua Helper x 1 (list)

  9. Post #9
    JohnnyOnFlame's Avatar
    February 2011
    2,234 Posts
    "Meta- (from Greek: μετά = "after", "beyond", "adjacent", "self"), is a prefix used in English (and other Greek-owing languages) to indicate a concept which is an abstraction from another concept, used to complete or add to the latter."

    Metatable is an Abstract table, containing functions, values and others.
    The idea of the metatable was created to help with the fact that there is no actual "object" or "entity" in Lua, so you create a table with Functions and Values as members to simulate the concept of objects.

    Hope I got this sorted out.

    The colon in "X:Y()" just means "Grab function member Y from Metatable X"
    Reply With Quote Edit / Delete Reply Windows 7 Brazil Show Events Lua Helper Lua Helper x 1 (list)

  10. Post #10
    Steins;Gate SUCKS
    Dave_Parker's Avatar
    October 2008
    5,063 Posts
    I think you can get a metatable of certain objects/entities.
    function _R.GetMetatable(Player).ColorGreen(self)
    self:SetColor(0, 200, 0, 255)
    end
    fix me if im wrong
    so now you can call on Player entity like ply:ColorGreen()
    FindMetaTable("Player") simply returns _R.Player.

    What you're doing would throw 2 errors, namely trying to call a function inside a function name, and trying to grab a nil table because you're trying to index the Player library inside the _R global.

    The correct form would be either

    local meta = FindMetaTable("Player")
    
    function meta.ColorGreen(self)
    self:SetColor(0,200,0,255)
    end
    

    or

    function _R.Player.ColorGreen(self)
    self:SetColor(0,200,0,255)
    end
    
    Reply With Quote Edit / Delete Reply Windows 7 Netherlands Show Events Lua Helper Lua Helper x 2 (list)

  11. Post #11
    VENEZOLANO
    Big Bang's Avatar
    August 2006
    3,419 Posts
    That's all good but you're forgetting the important part. What is a metatable?

    A metatable is Lua's emulation of classes in most Object Oriented Programming (OOP) languages. The implementation in Lua is, despite it being similar to the concept of a class, not quite alike. Every table has associated a metatable to it. The metatable is, put simply, another table on which Lua looks up any method or attribute the associated table doesn't have.

    Let's place a simple example. I assume you already have knowledge of what attributes and methods are. They're quite simple really, an attribute is a property of the object (A variable in a table, in Lua), and a method is a routine the object can perform (A function in a table). A metamethod is therefore just a method that exists on the metatable.

    local meta = {}
    meta.Number = 1
    
    local new = {}
    print( new.Number ) --Would print nil
    
    --We associate a metatable to our 'new' table
    setmetatable( new, meta )
    
    print( new.Number ) --Would print 1
    

    In this case here, the attribute Number doesn't exist on the 'new' table, nor is the attribute Number ever assigned to the 'new' table. The attribute Number however exists on the 'meta' table, and therefore, when the 'new' table has it's metatable set to 'meta', Lua, seeing as the attribute Number doesn't exist in the 'new' table, it looks for it on its metatable, it finds it, and returns it.

    Metatables aren't used only for simulating OOP in Lua, but that's their primary objective. Lua is particularly cumbersome for OOP due to tables being referenced in functions. What does this mean? Let's place an example.

    local tbl = {}
    
    print( tbl.Number ) --Would print nil
    
    function a( b )
    	b.Number = 1
    end
    
    a( tbl )
    
    print( tbl.Number ) --Would print 1

    As you can see here, the table passed to the function 'a' as a parameter isn't treated as a new table, it is treated as a reference to the table passed to it as a parameter, therefore all changes on it will be reflected on the table outside of the function. This allows for some fun stuff but it's always necessary to keep that in mind, specially when working with objects. Due to that behavior, constructors (The method that creates the object) need to do some unnecessarily funky stuff, like this.

    function meta:New()
    	local new = {}
    	setmetatable( new, self )
    	self.__index = self
    	return new
    end

    Otherwise, you would observe several instances of the same object (metatable) being treated as the same thing by Lua. This is why Lua isn't as ideal for OOP as for example, C++ or Java. It's nonetheless useful to learn as some things are so much easier when programmed with OOP than using the regular, structured programming we're all so used to.

    I encourage you to try it and experiment, you'll learn a whole deal of Lua if you do.
    Reply With Quote Edit / Delete Reply Windows 7 Venezuela Show Events Lua Helper Lua Helper x 1Lua King Lua King x 1 (list)

  12. Post #12
    Gold Member
    Divran's Avatar
    April 2008
    2,629 Posts
    local meta = {}
    meta.Number = 1
    
    local new = {}
    print( new.Number ) --Would print nil
    
    --We associate a metatable to our 'new' table
    setmetatable( new, meta )
    
    print( new.Number ) --Would print 1
    
    Actually, both these print nil, because you forgot
    meta.__index = meta
    :)

    (The __index variable specifies where to look for values which don't exist in the table.)

  13. Post #13
    VENEZOLANO
    Big Bang's Avatar
    August 2006
    3,419 Posts
    Actually, both these print nil, because you forgot
    meta.__index = meta
    :)

    (The __index variable specifies where to look for values which don't exist in the table.)
    Correct. The __index metamethod tells Lua where to look. Thank you.

  14. Post #14
    This is like the 3rd explanation I've seen of metatables on Facepunch and I still don't understand completely.

    Maybe I'm just not grasping it and failing to wrap my head around it.

    or I'm an idiot.
    Reply With Quote Edit / Delete Reply Windows XP United States Show Events Agree Agree x 1 (list)

  15. Post #15
    Surma's Avatar
    September 2010
    519 Posts
    Would it be correct to say that a metatable is an object (as in an instance of a class) and a metamethod is an object's method (one of them) the way java terminology defines it?

  16. Post #16
    Gold Member
    Divran's Avatar
    April 2008
    2,629 Posts
    Would it be correct to say that a metatable is an object (as in an instance of a class) and a metamethod is an object's method (one of them) the way java terminology defines it?
    I'd say no.
    A metatable is just a table, and a metamethod is just a method. Together, metatables, metamethods, and regular tables can be used to make objects in Lua.
    That's just how I see it, though.

  17. Post #17
    VENEZOLANO
    Big Bang's Avatar
    August 2006
    3,419 Posts
    Would it be correct to say that a metatable is an object (as in an instance of a class) and a metamethod is an object's method (one of them) the way java terminology defines it?
    Each table associated to a metatable would be an instance of a class, that class being the metatable. This isn't an entirely accurate representation but if you want to see it like Java then that's the correct analogy.
    Reply With Quote Edit / Delete Reply Windows 7 Venezuela Show Events Useful Useful x 1 (list)

  18. Post #18
    Please waste more of your money changing this title again.
    Gmod4ever's Avatar
    August 2005
    6,840 Posts
    This is like the 3rd explanation I've seen of metatables on Facepunch and I still don't understand completely.

    Maybe I'm just not grasping it and failing to wrap my head around it.

    or I'm an idiot.
    It's not your fault. It's more the fact that GLua is a bastardized hybrid. It's a mostly non-OO language that's trying to be an OO language in some regards, and stay a non-OO in others.

    If you were to study an entirely OO language, such as Java, then you would understand better where metatables and metamethods come from. Short of that, the approximate explanations given in this thread are about the closest you're going to get. In all honesty, I don't think metatables quite know exactly what they're trying to be, themselves.

    They are very related to classes in OO languages like Java, but not so closely related as to make a very accurate comparison. They're more like distant cousins than anything else.

  19. Post #19
    Surma's Avatar
    September 2010
    519 Posts
    Each table associated to a metatable would be an instance of a class, that class being the metatable. This isn't an entirely accurate representation but if you want to see it like Java then that's the correct analogy.
    Ok, thanks!