Explicit 'self'
Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 2 of 70.
When a function lives inside a table, it often needs to access or modify data within that same table. But here's the problem: how does the function know which table it belongs to?
The solution is to explicitly pass the table as the first argument to the function. By convention, this parameter is named self:
local counter = {
value = 0
}
function counter.increment(self)
self.value = self.value + 1
end
counter.increment(counter)
print(counter.value) -- Output: 1Notice how we call counter.increment(counter), passing the table itself as the argument. Inside the function, self now refers to that table, allowing us to read and modify self.value.
This pattern is essential because it lets the function work with the table's data without hardcoding the table's name. Consider a function that resets and returns the current count:
function counter.reset(self)
local old = self.value
self.value = 0
return old
end
print(counter.reset(counter)) -- Output: 1
print(counter.value) -- Output: 0While passing the table manually works, it can feel repetitive. In the next lesson, you'll learn a cleaner syntax that handles this automatically.
Challenge
EasyCreate a table named tracker with a field count initialized to 0.
Add a function tracker.addAmount(self, amount) that:
- Accepts
self(the table) as the first parameter - Accepts
amountas the second parameter - Adds
amounttoself.count
You will receive two inputs:
- First amount to add
- Second amount to add
Call tracker.addAmount twice (once for each input), passing the table as the first argument each time. After both calls, print the final value of tracker.count.
Cheat sheet
Functions inside tables can access table data by receiving the table as their first parameter, conventionally named self:
local counter = {
value = 0
}
function counter.increment(self)
self.value = self.value + 1
end
counter.increment(counter) -- Pass the table as argument
print(counter.value) -- Output: 1The self parameter allows the function to read and modify the table's fields without hardcoding the table name:
function counter.reset(self)
local old = self.value
self.value = 0
return old
end
print(counter.reset(counter)) -- Output: 1
print(counter.value) -- Output: 0Functions can accept additional parameters after self:
function counter.add(self, amount)
self.value = self.value + amount
end
counter.add(counter, 5)Try it yourself
-- Read input
local amount1 = tonumber(io.read())
local amount2 = tonumber(io.read())
-- TODO: Write your code below
-- Create a table named 'tracker' with a field 'count' initialized to 0
-- Add a function tracker.addAmount(self, amount) that adds amount to self.count
-- Call tracker.addAmount twice with the table as the first argument
-- Output the final count
print(tracker.count)This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1The 'Self' Concept
Tables with FunctionsExplicit 'self'The Colon SyntaxDot vs ColonRecap - Moving Point4Project: Digital Bank
Project SetupDeposit Method7Polymorphism & Overriding
Overriding MethodsCalling Parent MethodsDuck TypingCommon InterfaceChecking TypeRecap - Employee Roles10Project: Shape Manager
Project SetupRectangle Class2Class Prototype Pattern
The Prototype ConceptLinking with __indexThe :new() ConstructorInitializing AttributesIndependent InstancesRecap - Car Factory5Operator Overloading in OOP
Adding ObjectsSubtracting ObjectsConcatenating ObjectsComparing Objects (<, >)Recap - Wallet Math8Encapsulation
Naming ConventionsClosures for PrivacyAccess via ClosuresRead-Only TablesValidation LogicRecap - Secure Vault11Design Patterns (Lite)
Factory FunctionsSingleton TableIterator PatternObserver (Listener)Recap - Logger Factory3Object State and Behavior
Instance VariablesGetter MethodsSetter MethodsCalculated PropertiesFormatting StringsEquality ChecksRecap - Student Grade6Inheritance Basics
The Inheritance SetupInheriting MethodsExtending the ConstructorAdding Child MethodsShared vs UniqueRecap - Shape Hierarchy