The simple answer is this:
- Calling with a dot simply calls that function on it’s own.
- Calling with a colon passes the variable to the left of the colon as the first parameter in the function.
For example, let’s create an object (always a table, in Lua) and also create a function…
local t = {} local function doAthing( paramA, paramB ) print( paramA, paramB ) end
We can make the function a property of the table object, like this…
t.doAthing = doAthing
or like this (if we didn’t write it earlier)…
function t:doAthing( paramA, paramB ) print( paramA, paramB ) end
or even like this…
local t = { doAthing = function( paramA, paramB ) print( paramA, paramB ) end }
Now, if we look at the first version of that function, we can call it on it’s own, like this:
doAthing( "one thing", "another thing" )
Both of the parameters that we pass in get received inside the function as their named values.
But, once we’ve declared the function as a property of a table, we can call it “on the table”, like this…
t.doAthing( "one thing", "another thing" )
That is exactly the same as the previous call - both parameters are received exactly the same way.
We can also call it with the colon, which basically tells the function about the object which it is “being called on”, like this…
t:doAthing( "one thing", "another thing" )
The only difference here is that the two parameters, paramA and paramB, will be the table ‘t’ and the string “one thing” - “another thing” will get lost.
So, why is this useful?
Because you can write a function which doesn’t know anything about it’s parent object but still reference that parent object. Here’s what I mean…
Let’s say I want a function which will print a string property called “.class” of whatever table it is assigned to. I could create a bunch of tables all with different .class values…
local a = { class="first" } local b = { class="bee" } local c = { class="the sea" }
I could also create a function with the standard first parameter called ‘self’ and use that to get the table which the function has been assigned to (it doesn’t matter what that parameter is called, but ‘self’ is a convention.)…
local function printMyClass( self ) print( "My parent's class is: "..self.class ) end
I could then assign that function to all of those tables…
a.printMyClass = printMyClass b.printMyClass = printMyClass c.printMyClass = printMyClass
I can even create another one with the same class assigned to it but in a more creative way…
local d = { class = "I got a D :(" classPrinter = printMyClass }
So now, if I were to call all of those table’s printMyClass() functions they would print their parent’s .class property out - bear in mind that I effectively use a different name for the last one…
a:printMyClass() d:printMyClass() c:printMyClass() d:classPrinter()
And this would output…
first bee the sea I got a D :(