• 3 Things That I Cant Understand About Lua.
    18 replies, posted
  • Avatar of LuaGuy
  • 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. [highlight](User was banned for this post ("Wrong section" - mahalis))[/highlight]
  • Avatar of Treelor
  • In my limited experience with lua, the colon represents the separation between an entity and a command operating on that entity.
  • Avatar of LuaGuy
  • [QUOTE=StickyNade;34777154]In my limited experience with lua, the colon represents the separation between an entity and a command operating on that entity.[/QUOTE] 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 ?
  • Avatar of Gmod4ever
  • 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[/code] Now, as you go along, you realize that it becomes a bit tiredsome to do [b]Object.ColorMePink(Object)[/b] 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 [b]Object.ColorMePink()[/b], and, since it's stored on Object, it'll automatically assume that I mean to do [b]Object.ColorMePink(Object)[/b]. And thusly, you add the colon syntax. Now instead of having to do [b]Object.ColorMePink(Object)[/b] every time you want to color Object pink, you can now simply do [b]Object:ColorMePink()[/b]. Put another way, [b]Object.ColorMePink(Object)[/b] and [b]Object:ColorMePink()[/b] 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[/code] 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[/code] These operate exactly the same in calling it: [code][code]Object.SomeFunction(Object) Object:SomeFunction()[/code][/code] 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[/code] You can do either of these methods: [b]Object.SomeFunction(Object,1,2,3)[/b] or [b]Object:SomeFunction(1,2,3)[/b]. 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[/code] 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.
  • Avatar of LuaGuy
  • [QUOTE=Gmod4ever;34777503]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[/code] Now, as you go along, you realize that it becomes a bit tiredsome to do [b]Object.ColorMePink(Object)[/b] 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 [b]Object.ColorMePink()[/b], and, since it's stored on Object, it'll automatically assume that I mean to do [b]Object.ColorMePink(Object)[/b]. And thusly, you add the colon syntax. Now instead of having to do [b]Object.ColorMePink(Object)[/b] every time you want to color Object pink, you can now simply do [b]Object:ColorMePink()[/b]. Put another way, [b]Object.ColorMePink(Object)[/b] and [b]Object:ColorMePink()[/b] 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[/code] 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[/code] These operate exactly the same in calling it: [code][code]Object.SomeFunction(Object) Object:SomeFunction()[/code][/code] 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[/code] You can do either of these methods: [b]Object.SomeFunction(Object,1,2,3)[/b] or [b]Object:SomeFunction(1,2,3)[/b]. 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[/code] 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.[/QUOTE] This is mind blowing but very satisfactory explanation. So i dont have to use colon ? It is just an alternative way ? Thanks anyway.
  • Avatar of Dave_Parker
  • [QUOTE=LuaGuy;34777736]This is mind blowing but very satisfactory explanation. So i dont have to use colon ? It is just an alternative way ? Thanks anyway.[/QUOTE] 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)
  • Avatar of LuaGuy
  • [QUOTE=Dave_Parker;34777750]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)[/QUOTE] 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 ?
  • Avatar of Rimbas
  • I think you can get a metatable of certain objects/entities. [lua]function _R.GetMetatable(Player).ColorGreen(self) self:SetColor(0, 200, 0, 255) end[/lua] fix me if im wrong so now you can call on Player entity like ply:ColorGreen()
  • "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"
  • Avatar of Dave_Parker
  • [QUOTE=aurum481;34784861]I think you can get a metatable of certain objects/entities. [lua]function _R.GetMetatable(Player).ColorGreen(self) self:SetColor(0, 200, 0, 255) end[/lua] fix me if im wrong so now you can call on Player entity like ply:ColorGreen()[/QUOTE] 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 [lua] local meta = FindMetaTable("Player") function meta.ColorGreen(self) self:SetColor(0,200,0,255) end [/lua] or [lua] function _R.Player.ColorGreen(self) self:SetColor(0,200,0,255) end [/lua]
  • Avatar of fnox
  • 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. [lua] 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 [/lua] 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. [lua]local tbl = {} print( tbl.Number ) --Would print nil function a( b ) b.Number = 1 end a( tbl ) print( tbl.Number ) --Would print 1[/lua] 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 [I]reference[/I] 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. [lua]function meta:New() local new = {} setmetatable( new, self ) self.__index = self return new end[/lua] 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.
  • Avatar of Divran
  • [QUOTE=Big Bang;34787048][lua] 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 [/lua][/QUOTE] Actually, both these print nil, because you forgot [lua]meta.__index = meta[/lua] :) (The __index variable specifies where to look for values which don't exist in the table.)
  • Avatar of fnox
  • [QUOTE=Divran;34788028]Actually, both these print nil, because you forgot [lua]meta.__index = meta[/lua] :) (The __index variable specifies where to look for values which don't exist in the table.)[/QUOTE] Correct. The __index metamethod tells Lua where to look. Thank you.
  • Avatar of Kidd
  • 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.
  • Avatar of Surma
  • Would it be correct to say that a metatable [i]is[/i] an object (as in an instance of a class) and a metamethod [i]is[/i] an object's method (one of them) the way java terminology defines it?
  • Avatar of Divran
  • [QUOTE=Surma;34789620]Would it be correct to say that a metatable [i]is[/i] an object (as in an instance of a class) and a metamethod [i]is[/i] an object's method (one of them) the way java terminology defines it?[/QUOTE] 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.
  • Avatar of fnox
  • [QUOTE=Surma;34789620]Would it be correct to say that a metatable [i]is[/i] an object (as in an instance of a class) and a metamethod [i]is[/i] an object's method (one of them) the way java terminology defines it?[/QUOTE] 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.
  • Avatar of Gmod4ever
  • [QUOTE=Kidd;34788596]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.[/QUOTE] 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.
  • Avatar of Surma
  • [QUOTE=Big Bang;34796238]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.[/QUOTE] Ok, thanks!