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.
Programming in Lua | ||
Part III. The Standard Libraries Chapter 23. The Debug Library |
The debug
library also allows us to
access the upvalues that a Lua function uses,
with getupvalue
.
Unlike local variables, however,
a function has its upvalues even when it is not active
(this is what closures are about, after all).
Therefore, the first argument for getupvalue
is not a stack level,
but a function (a closure, more precisely).
The second argument is the upvalue index.
Lua numbers upvalues in the order they are first referred in a function,
but this order is not relevant,
because a function cannot have two upvalues with the same name.
You can also update upvalues,
with debug.setupvalue
.
As you might expect, it has three parameters:
a closure, an upvalue index, and the new value.
Like setlocal
, it returns the name of the upvalue,
or nil if the upvalue index is out of range.
The following code shows how we can access the value of any given variable of a calling function, given the variable name:
function getvarvalue (name) local value, found -- try local variables local i = 1 while true do local n, v = debug.getlocal(2, i) if not n then break end if n == name then value = v found = true end i = i + 1 end if found then return value end -- try upvalues local func = debug.getinfo(2).func i = 1 while true do local n, v = debug.getupvalue(func, i) if not n then break end if n == name then return v end i = i + 1 end -- not found; get global return getfenv(func)[name] endFirst, we try a local variable. If there is more than one variable with the given name, we must get the one with the highest index; so we must always go through the whole loop. If we cannot find any local variable with that name, then we try upvalues. First, we get the calling function, with
debug.getinfo(2).func
,
and then we traverse its upvalues.
Finally, if we cannot find an upvalue with that name,
then we get a global variable.
Notice the use of the argument 2 in the calls
to debug.getlocal
and debug.getinfo
to access the calling function.
Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved. |