Static Members
Static members are shared across all instances of a class. Changes to a static member affect every instance.
Static Variables
A static variable has one value shared by all instances:
local a = Counter.new()
print(a:getCount()) -- 1
local b = Counter.new()
print(b:getCount()) -- 2
local c = Counter.new()
print(c:getCount()) -- 3
-- All instances see the same value
print(a:getCount()) -- 3
Accessing Static Members
Static members can be accessed from both instances and the class itself:
class "Config" {
static {
maxPlayers = 100;
serverName = "My Server";
};
}
-- Access from class
print(Config.maxPlayers) -- 100
print(Config.serverName) -- My Server
-- Access from instance
local c = Config.new()
print(c.maxPlayers) -- 100
-- Changes affect everything
Config.maxPlayers = 50
print(c.maxPlayers) -- 50 (same value)
Static Methods
Static methods don't require an instance and can be called directly on the class:
-- Call directly on class
print(MathUtils:circleArea(5)) -- 78.53975
print(MathUtils:circleCircumference(5)) -- 31.4159
-- Or on an instance (less common)
local m = MathUtils.new()
print(m:circleArea(5)) -- 78.53975
Private Static
Combine private and static for shared internal state:
print(IdGenerator:generate()) -- 1
print(IdGenerator:generate()) -- 2
print(IdGenerator:generate()) -- 3
-- Cannot access private static directly
print(IdGenerator.nextId) -- Error: accessing private member
IdGenerator:reset()
print(IdGenerator:generate()) -- 1
Static vs Instance Members
Understanding the difference:
class "Example" {
static {
sharedValue = 0;
};
instanceValue = 0;
}
local a = Example.new()
local b = Example.new()
-- Instance values are separate
a.instanceValue = 10
b.instanceValue = 20
print(a.instanceValue) -- 10
print(b.instanceValue) -- 20
-- Static values are shared
a.sharedValue = 100
print(b.sharedValue) -- 100 (same value!)
print(Example.sharedValue) -- 100
Static Initializer: __register
The __register method runs once when the class is defined. Use it to initialize static members that require computation or to register the class somewhere.
This is similar to Java's static {} initializer block. The self parameter refers to the class itself, not an instance.
Memory Efficiency
Static members are not copied when creating new instances, saving memory for large data:
class "Game" {
static {
-- This large table is shared, not copied
levelData = {
-- lots of level configuration...
};
};
currentLevel = 1; -- This is copied per instance
}
-- Creating 1000 players doesn't duplicate levelData
for i = 1, 1000 do
Game.new()
end
Complete Example
dofile("simploo.lua")
class "Player" {
private {
static {
allPlayers = {};
};
};
public {
static {
getPlayerCount = function(self)
return #self.allPlayers
end;
getAllPlayers = function(self)
return self.allPlayers
end;
broadcast = function(self, message)
for _, player in ipairs(self.allPlayers) do
player:receive(message)
end
end;
};
name = "";
__construct = function(self, playerName)
self.name = playerName
table.insert(self.allPlayers, self)
print(self.name .. " joined. Total players: " .. #self.allPlayers)
end;
receive = function(self, message)
print("[" .. self.name .. "] " .. message)
end;
};
}
local alice = Player.new("Alice") -- Alice joined. Total players: 1
local bob = Player.new("Bob") -- Bob joined. Total players: 2
local charlie = Player.new("Charlie") -- Charlie joined. Total players: 3
print(Player:getPlayerCount()) -- 3
Player:broadcast("Game starting!")
-- [Alice] Game starting!
-- [Bob] Game starting!
-- [Charlie] Game starting!
dofile("simploo.lua")
local player = class("Player")
player.private.static.allPlayers = {}
player.public.name = ""
function player.public.static:getPlayerCount()
return #self.allPlayers
end
function player.public.static:getAllPlayers()
return self.allPlayers
end
function player.public.static:broadcast(message)
for _, p in ipairs(self.allPlayers) do
p:receive(message)
end
end
function player.public:__construct(playerName)
self.name = playerName
table.insert(self.allPlayers, self)
print(self.name .. " joined. Total players: " .. #self.allPlayers)
end
function player.public:receive(message)
print("[" .. self.name .. "] " .. message)
end
player:register()
local alice = Player.new("Alice") -- Alice joined. Total players: 1
local bob = Player.new("Bob") -- Bob joined. Total players: 2
local charlie = Player.new("Charlie") -- Charlie joined. Total players: 3
print(Player:getPlayerCount()) -- 3
Player:broadcast("Game starting!")
-- [Alice] Game starting!
-- [Bob] Game starting!
-- [Charlie] Game starting!