self is a parameter automatically passed in when you use a colon to make a function, i.e.
function foo:bar()
print(self)
end
foo:bar() -- in this case, self would be the foo table
-- this is also equivalent to
function foo.bar(self)
print(self)
end
foo.bar(foo)
self is generally used in object oriented programming. For example, if I was trying to make a game where all the cars are pretty much the same thing with different models and stats, we might use OOP.
local car = {}
car.__index = {}
-- how we create a car
-- we don't use colon because we don't really care how new is being called, just the
-- parameters that might be passed in
function car.new(model, speed)
local newCar = {
model = model,
speed = speed
}
return setmetatable(newCar, car)
end
-- here we do care about self
-- we want the function to print the car's speed, not the speed of another car
function car.__index.Drive()
print("the car vrooms at " .. speed)
end
return car
There’s probably use of self outside of OOP, but this is the one I use most often.
P.S. Please don’t slam OOP into everything, a lot of scripts are simpler without OOP,
Self is an implicit parameter that references itself (it’s in the name) as in the location from which a method is called if done with colon syntax. These are equivalent:
function foobar.frobnicate(self) -- foobar:frobnicate()
function foobar:frobnicate() -- foobar.frobnicate(foobar)
Generally speaking you only ever need self for stateful objects so you can update the object’s state specifically without accidentally doing it on a class-level or frameworks structured in such a way that code in the framework has other pieces injected (see AeroGameFramework as an example).
There aren’t very many cases where you need it besides statefulness or deliberate architecture. If you see it a lot, most likely it’s either in object-oriented programming as mentioned earlier or because a developer likes the way it looks even though it’s entirely unnecessary and you can use dot syntax.