This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

23.1.1 – Accessing Local Variables

You can access the local variables of any active function by calling getlocal, from the debug library. It has two parameters: the stack level of the function you are querying and a variable index. It returns two values: the name and the current value of that variable. If the variable index is larger than the number of active variables, getlocal returns nil. If the stack level is invalid, it raises an error. (You can use debug.getinfo to check the validity of a stack level.)

Lua numbers local variables in the order that they appear in a function, counting only the variables that are active in the current scope of the function. For instance, the code

    function foo (a,b)
      local x
      do local c = a - b end
      local a = 1
      while true do
        local name, value = debug.getlocal(1, a)
        if not name then break end
        print(name, value)
        a = a + 1
    foo(10, 20)
will print
    a       10
    b       20
    x       nil
    a       4
The variable with index 1 is a (the first parameter), 2 is b, 3 is x, and 4 is another a. At the point where getlocal is called, c is already out of scope, while name and value are not yet in scope. (Remember that local variables are only visible after their initialization code.)

You can also change the values of local variables, with debug.setlocal. Its first two parameters are a stack level and a variable index, like in getlocal. Its third parameter is the new value for that variable. It returns the variable name, or nil if the variable index is out of scope.