Encapsulation with Closures
Hide private state using closure-based object patterns.
Closure-Based Objects
An alternative to metatable OOP: use a closure to hide state. The object is a table of functions; all functions close over private variables. No metatable needed. Truly private state that's unreachable from outside.
local function makeCounter(start)
local count = start or 0 -- truly private
return {
increment = function() count=count+1 end,
decrement = function() count=count-1 end,
get = function() return count end,
reset = function() count=0 end,
}
end
local c = makeCounter(10)
c.increment(); c.increment()
print(c.get()) -- 12
print(c.count) -- nil (truly private!)Private vs Public
With closures, the distinction between private and public is absolute: closures share the upvalue (private), external code only sees the returned table (public). No way to access private variables without going through the public API.
local function makeAccount(initial)
local balance = initial
local transactions = {}
local function record(type, amount)
transactions[#transactions+1] = {type=type,amount=amount}
end
return {
deposit = function(n) record("D",n); balance=balance+n end,
withdraw = function(n)
if n>balance then error("insufficient funds") end
record("W",n); balance=balance-n
end,
balance = function() return balance end,
history = function() return transactions end,
}
endAll lessons in this course
- Classes via Metatables
- Constructors and new()
- Instance Methods and self
- Encapsulation with Closures