Updated the whole answer
Lua is not an Object Oriented Program, which is why we use tables and metatables to replicate one. Your line was as follows
function void:void ()
The first void
is refered to the table that contains the function. Since void:void
is pretty confusing, let me instead say Blueprint:void
.
function Blueprint:void ()
.
The Blueprint
table contains the function void
. The interesting thing to note here is the :
. Typically, when creating functions which go inside the table, we use .
.
3 | function Blueprint.void () { ... } ; |
is the same as
2 | function void () { ... } ; |
as you may have know already
But the :
is really unique, especially to Object Oriented Programming. You have used methods everywhere.
game:GetService()
, game:FindService()
, Part:Destroy()
, Object:GetChildren()
and etc. They are all methods which uses the :
. Why is that?
This is because function Tab:Func ()
is another way of saying function Tab.Func(Tab)
. When we use :
, we do not need to reference itself again. When referencing the table the function contains, people generally use the variable self
. Although it syntax highlights in ROBLOX, it is not a vairable.
Now lets see some practical usage of :
in Programming.
06 | return setmetatable (template, Class); |
09 | function Class:coutMessage (message) |
14 | local zafirua = Class.new (); |
15 | zafirua:coutMessage( "Hello I am Zafirua" ); |
Let's talk about what this code does line by line!
First line, we created a main Blueprint called Class
. It is a table
and will hold all of our functions or values or metavalues. The next line, we use the __index
metamethod since we want the object to inherit its methods and/or its properties.
'__index' is a really vast metamethod. It is almost used in every single OOP classes in Lua. When you want to access to a non-existing key inside a Lua table, the result is nil
. For example,
would print nil
. Now you may assume that the reason it is printing nil
is because it looked through the table t
and did not find any key called a
and it returned nil. Now while that is kinda right, it isn't. When it cannot find the key called a
, it then checks to see if there is a metatable attached to it. If it exists, it then returns the key's value. Else, it returns nil. An obvious example is as follows.
08 | setmetatable (template, Class); |
It prints the Class.a
's value which is 1
!
The fourth line, we create a new function called new
. What this does is that it allows us to create a new object that will inherit the properites of Class
! The next line, we created a new table called Template
. and using the setmetatable
which simple assigns Metatable to another table, we attached Class
to Template
!
With this, we can actually reference all of Class
's methods without actually calling the Class. What do I mean by that?
Say for example the Class
table contained a function called printName
. Since the Class allows inheitance because of __index
, and the Class metatable is set to Template
, we can do Template:printName()
as opposed to Class:printName()
!
Now, you will realize that we aren't actually using Template:printName()
but zafirua:printName()
. And the reason why is because zafirua
is actually a reference to Template
. So technically we kinda are doing Template:printName()
If this paragraph confused you, think of it like this.
7 | local zafirua = Template; |
Then we called the printName()
method and it printed the message.
If you wanted to write function Class:printName(message)
in different approach, you would do
function Class.printName(self, message)
where self
means whichever object is calling this method. In our case, the object is called zafirua
. So the parameter that is seen internally is function Class.printName(zafirua, "Hello I am Zafirua!");
I hope this made much more sense to you. If it did, please be sure to accept the answer. If not, please do not hesitate to ask for clarification.