Menu
CoddyTech

Self and Colon Methods

Part of the Introduction To Luau section of Coddy's Lua journey. Lesson 45 of 80.

Writing rect.area(rect) works, but you learned a better way back in Lua OOP: the colon. rect:area() is exactly the same call: Lua passes the table before the colon as the first argument, self, automatically.

The colon helps at the definition site too. function account:deposit(amount) declares a hidden first parameter named self for you:

type Account = {
    owner: string,
    balance: number,
    deposit: (self: Account, amount: number) -> (),
    getBalance: (self: Account) -> number,
}

local account = {owner = "Maya", balance = 1500}

function account:deposit(amount: number)
    self.balance += amount -- self is implicit
end

function account:getBalance(): number
    return self.balance
end

Notice how the shape declares self explicitly, deposit: (self: Account, amount: number) -> (), even though the colon hides it in the implementation. The colon is sugar; the parameter is still there, and the type spells it out. A method that returns nothing is typed with the empty return -> ().

Calling follows the same rule you already know: account:deposit(250) is identical to account.deposit(account, 250). Same runtime behavior as your OOP chapter: Luau just adds types on top.

Notice that account itself is left unannotated. The Account type describes the finished table, and the table only matches it once both methods are attached; local account: Account = {owner = "Maya", balance = 1500} would make strict mode report the missing methods.

challenge icon

Challenge

Easy

Attach two methods to an account with colon syntax.

  1. Under the table, define function account:deposit(amount: number) that adds amount to self.balance.
  2. Define function account:getBalance(): number that returns self.balance.
  3. Print account:getBalance(), call account:deposit(120), then print account:getBalance() again.

Press Run Code: the output shows 300, then 420.

Try it yourself

type Account = {
    owner: string,
    balance: number,
    deposit: (self: Account, amount: number) -> (),
    getBalance: (self: Account) -> number,
}

local account = {owner = "Noah", balance = 300}

-- 1) function account:deposit(amount: number)
-- 2) function account:getBalance(): number
-- 3) print the balance, deposit 120, print it again

All lessons in Introduction To Luau

Practice on your own: Online Luau compiler