Menu
Coddy logo textTech

Instance Variables

Part of the Object Oriented Programming section of Coddy's Lua journey — lesson 12 of 70.

Welcome to a new chapter focused on how objects manage their internal data. You've learned to create classes and instances—now it's time to explore how each instance stores and manages its own unique state.

Instance variables are fields that belong exclusively to a single object. When you assign a value to self.something inside a method or constructor, that data lives only in that particular instance. Other objects of the same class have their own separate copies.

This becomes especially important when storing complex data like tables. Consider an inventory system where each character carries different items:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- Each instance gets its own empty table
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

The key line is instance.items = {}. By creating a new empty table inside the constructor, every inventory object receives its own distinct list. If you instead defined items in the class table itself, all instances would accidentally share the same table—adding a sword to one character would give it to everyone!

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- Output: 1
print(#bag2.items)  -- Output: 1

Each inventory maintains its own collection. This pattern applies whenever an instance needs to track data that changes independently—lists, counters, or any mutable state unique to that object.

challenge icon

Challenge

Easy

Let's build a ShoppingCart system where each cart maintains its own separate list of products. This will demonstrate how instance variables keep data isolated between objects—adding items to one cart won't affect another!

You'll organize your code across two files:

  • ShoppingCart.lua: Define your ShoppingCart class where each instance has its own products table. Include:
    • A :new() constructor that initializes an empty products list for each cart
    • An :addProduct(productName) method that adds a product to this cart's list
    • A :listProducts() method that prints each product on a separate line
  • main.lua: Require your ShoppingCart module and create two separate carts. Add different products to each cart to prove they maintain independent inventories.

You will receive four inputs:

  1. First product to add to cart A
  2. Second product to add to cart A
  3. First product to add to cart B
  4. Second product to add to cart B

In your main file:

  1. Create two shopping carts: cartA and cartB
  2. Add the first two products to cartA
  3. Add the last two products to cartB
  4. Print Cart A: then list cart A's products
  5. Print Cart B: then list cart B's products

For example, if the inputs are Apple, Bread, Milk, and Eggs, the output should be:

Cart A:
Apple
Bread
Cart B:
Milk
Eggs

Remember: the key is initializing products as a new empty table inside the constructor. This ensures each cart instance gets its own separate list rather than sharing one table across all carts.

Cheat sheet

Instance variables are fields that belong exclusively to a single object. When you assign a value to self.something inside a method or constructor, that data lives only in that particular instance.

To create instance variables, initialize them inside the constructor using a new table for each instance:

local Inventory = {}
Inventory.__index = Inventory

function Inventory:new()
    local instance = {}
    setmetatable(instance, self)
    instance.items = {}  -- Each instance gets its own empty table
    return instance
end

function Inventory:addItem(item)
    table.insert(self.items, item)
end

The key is instance.items = {}—creating a new empty table inside the constructor ensures every object receives its own distinct data. If you defined items in the class table itself, all instances would share the same table.

local bag1 = Inventory:new()
local bag2 = Inventory:new()

bag1:addItem("Sword")
bag2:addItem("Potion")

print(#bag1.items)  -- Output: 1
print(#bag2.items)  -- Output: 1

Each instance maintains its own collection independently. This pattern applies to any mutable state unique to an object—lists, counters, or other data that changes per instance.

Try it yourself

-- Require the ShoppingCart module
local ShoppingCart = require('ShoppingCart')

-- Read inputs
local product1 = io.read()
local product2 = io.read()
local product3 = io.read()
local product4 = io.read()

-- TODO: Create two shopping carts: cartA and cartB

-- TODO: Add product1 and product2 to cartA

-- TODO: Add product3 and product4 to cartB

-- TODO: Print "Cart A:" then list cartA's products

-- TODO: Print "Cart B:" then list cartB's products
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming