> I'm considering lua for a specific project. One
of my needs is for static
> variables that retain their value from one invocation of a function
to the
> next. In a quick reading of the manual section on variable scoping,
I saw
> no mention of static variables. Does lua provide static variables?
Did I
> miss something while reading the manual?
Yes it does, but perhaps not in the form you are used
to (which I assume is C/C++).
The following is probably the simplest example; I
have put it in a superfluous do/end block so you can try it from the
standalone interpreter.
do local accum = 0 function put(change) if accum + change < 0 then error "You
are overdrawn!" end accum = accum + change return accum end
function balance() return accum end
end
> =balance() 0 > =put(20) 20 > =put(-10) 10 > =put(-15) stdin:4: You are overdrawn! stack traceback: [C]: in function `error' stdin:4: in function `put' (tail call): ? [C]: ? > =balance() 10
You will notice that the variable accum is shared
by the two functions put() and balance() although it is not available in the rest of the program.
Normally, this would be more useful as a kind of "object", using a factory function
(or constructor, if you prefer).
function account(initial) local accum = initial local self = {} function self.put(change) if accum + change < 0 then error
"You are overdrawn!" end accum = accum + change return accum end function self.balance() return accum end return self end
> bob = account(20) > joe = account(10) > joe.put(-5) > bob.put(5) > =joe.balance() 5 > =bob.balance() 25
From this we could derive:
function transfer(payer, payee, amount) if amount < 0 then return transfer(payee,
payer, -amount) end assert(pcall(payer.put, -amount), "Not
enough in payer account") payee.put(amount) end
> =transfer(bob, joe, 20) > =joe.balance() 25 > =bob.balance() 5 > =transfer(joe, bob, 40) stdin:3: Not enough in payer account stack traceback: [C]: in function `assert' stdin:3: in function `transfer' (tail call): ? [C]: ? > =joe.balance() 25 > =bob.balance() 5
I believe there is an example very like this one in
Roberto's excellent book.