lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



> 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.


R.