You need a table to carry the function (or method) and all the information it needs to run.
If we use the Person example, then you have a function called "speak" which takes a name:
Code: Select all
function speak( name )
print ( "Hello, my name is " .. name )
end
Now, if you have a table containing information about someone, you can make them say their name:
Code: Select all
personA = { name = "Tim" }
speak( personA.name )
-- prints Hello my name is Tim
However, this is kinda annoying because you now have the function seperate from the table of information. What you really want, is for them to be together. So you add the function to the table itself:
Code: Select all
personA =
{
name = "Tim",
speak = function( name ) print( "Hello, my name is " .. name )
}
This is helpful because if you ever need to change the function, you know where to find it. It's near the table that holds the information that the function wants to use. And you can call it like this:
But this seems like a lot of overhead. And it doesn't make sense that you have to specify what field from the table to use as the name. Since the function is designed to work
only with this object (at this time), you already know the right field. So you can just select the right field of the table in the function instead. So now you get:
Code: Select all
personA =
{
name = "Tim",
speak = function( person ) print( "Hello, my name is " .. person.name )
}
personA.speak( personA )
This allows you to get rid of having to specify the name field every time you call the function. That's a little cleaner. But we still have to pass the table twice; once to determine where the function is and then once to say that we want to add the same table as its argument.
Now there isn't
really a way to deal with this. After all; the function is just a function. It doesn't know it's inside a table, nor that it can read fields from that table.
Fortunately Lua includes a little trick that lets us get rid of the double declaration. That's the one where you write a colon. It doesn't
actually change anything, it's just more convienient. However, because we're hiding away the table passed to the function (since that's the goal of the trick; to not have to specify the table twice) we now need some way to determine how to access that table, since its name is no longer available.
So, Lua simply defaults to calling it "self", since this term sorta makes sense (not exactly, but close enough). "Self" then simply means "The table this function is stored in".
So now we write this:
Code: Select all
personA = {
name = "Tim"
}
function personA:speak() print( "Hello, my name is " .. self.name ) end
Now as I said; effectively this is
exactly the same as writing this:
Code: Select all
personA.speak = function( self ) print( "Hello, my name is " .. self.name ) end
Which, itself, is still the same as writing this:
Code: Select all
personA.speak = function( personA ) print( "Hello, my name is " .. personA.name ) end
Because it doesn't really matter how you name variables, that's just helping yourself. But because the a:b() notation doesn't require us to specify a name for the parameter we pass to the function, we need some kind of sensible default on how to access the table that the function is defined on. And that's "self".
I hope this makes sense. If there's any problems, just point out the step where you're having issues and I'll try to clarify further.