lua-users home
lua-l archive

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


When a lone identifier, say id, occurs in a piece of Lua 5.2 code, the
following happens:
1) If a local variable called id is found, then the identifier refers
to that local.
2) Otherwise, if an upvalue called id is found, then the identifier
refers to that upvalue.
3) Otherwise, the identifier is replaced by _ENV.id, and the process restarted.

There is always a local or upvalue called _ENV, so the above process
always terminates. When a chunk of Lua code is loaded, it is done so
as if "local _ENV = DEFAULT_ENV" is present at the top of the chunk
(hence why there is always something called_ENV), where DEFAULT_ENV is
a special value pulled out of the registry. If it were defined, then
the definition of DEFAULT_ENV would look something like:
DEFAULT_ENV = {
  _G = DEFAULT_ENV,
  print = <C function>,
  ...
}

This should explain where _G comes from, and why it is equal to _ENV
until you change _ENV to be something other than the default.

Moving onto locals, local variables exist transiently in a magic place
(the stack) precisely for the duration of the relevant function call /
scope within the call. As with other programming languages, the stack
gets re-used for the locals of future function calls.

Finally, upvalues live as part of a function instantiation. In OOP
languages, it is common to say that a class gets instantiated, with
the instance knowing what kind of class it is, along with having
copies of the call variables. In Lua, function instantiation is
similar; an instance of a function (called a closure) knows which
function it is, along with having copies of the upvalues (though some
upvalues may be shared with other closures, and/or temporarily shared
with local variables of active functions).

On Sat, Mar 31, 2012 at 6:34 PM, Jose Torre-Bueno <jtorrebueno@cox.net> wrote:
> This may seem naive but I am teaching myself Lua and seem to be missing
> something important.
>
> Reading the discussion of _ENV (in 5.2) I got the impression that local
> variables were stored in the  _ENV of that function and upvalues to defined
> functions were therefore stored in a copy of the  _ENV of the function that
> did the definition .  I wrote the following test snippet to check this:
>
> function f(x)
> print'in f'
> local fvar = x
> print(_G, _ENV)
> print(_G.fvar,_ENV.fvar)
> function g()
> print'in g'
> local gvar = 888
> print(_G, _ENV)
> print(gvar, fvar)
> print(_G.fvar,_ENV.fvar, _G.gvar,_ENV.gvar )
> end
> end
>
> but this gives the result:
>
>> f(1000)
> in f
> table: 0x100100e50 table: 0x100100e50
> nil nil
>> g()
> in g
> table: 0x100100e50 table: 0x100100e50
> 888 1000
> nil nil nil nil
>>
>
> Obviously things do not work the way I imagined.  _ENV is always equal to _G
> and I don't understand where either local variables or upvalues live.  This
> despite the fact that g() clearly is getting the correct upvalue.
>
> I feel that I will not make any progress until I understand this critical
> point.  Can anybody give some advice to a new student?
> Thanks
>
>
>
> Jose Torre-Bueno
> jtorrebueno@cox.net
>
>
>
>