I’ve been studying a bit more on Lua API to strengthen my ability, and I came across this weird method of writing a function that I personally have never seen before, the formality look somewhat like this, function void:void()
. Could someone explain this to me? Also is there a possible way to write this as a local function or variable, I.e local void:void = function()?
Thank you!
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 .
.
local Blueprint = {}; function Blueprint.void () {...};
is the same as
local Blueprint = { 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.
local Class = {}; Class.__index = Class; function Class.new () local template = {}; return setmetatable (template, Class); end function Class:coutMessage (message) print(message); end local zafirua = Class.new (); 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,
local t = {}; print(t.a);
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.
local Class = { a = 1; }; Class.__index = Class; local template = {}; setmetatable(template, Class); print(template.a);
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.
local t1 = {1, 2, 3}; local t2 = t1; -- and local Template = {--Contains all the methods from super class called "Class"}; 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.