lua-users home
lua-l archive

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


2014-06-02 3:10 GMT+02:00 Robert Virding <rvirding@gmail.com>:
> Reading through the manual I have understood that:
>
> - _ENV is an upvalue to a chunk and not an argument to the chunk function
> - It is the only upvalue to the chunk
>
> Am I correct here? There is a slightly cryptic section in the documentation
> of load which has me puzzled:
>
> "If the resulting function has upvalues, the first upvalue is set to the
> value of the global environment or to env, if that parameter is given. When
> loading main chunks, the first upvalue will be the _ENV variable (see
> §2.2)."
>
> I am assuming that the resulting function is the chunk function.

The debug library is your friend.

$ lua upvaldemo.lua

Calling `upvaldemo(upvaldemo)`
This is an anonymous Lua function.
It has 1 fixed parameter.
Upvalue #1 at 0x241bbd0 is named _ENV and has value 'table: 0x24155f0'

Calling `upvaldemo(bytecode)
This is an anonymous Lua function.
It has 1 fixed parameter.
Upvalue #1 at 0x241cef0 is named _ENV and has value 'table: 0x24155f0'

Calling `upvaldemo(pairs)`
This is an anonymous C function.
It has 0 fixed parameters and '...'.

Calling `upvaldemo(f)` for a local function
This is an anonymous Lua function.
It has 1 fixed parameter and '...'.
Upvalue #1 at 0x2420ab0 is named a and has value '1'
Upvalue #2 at 0x2420ae0 is named c and has value '3'
Upvalue #3 at 0x241bbd0 is named _ENV and has value 'table: 0x24155f0'

Calling `upvaldemo(0)` from inside running local function `f`
This is a C function named 'getinfo' in some table.
It has 0 fixed parameters and '...'.

Calling `upvaldemo(1)` from inside running local function `f`
This is a global Lua function named 'upvaldemo'.
It has 1 fixed parameter.

Calling `bytecode(1)` from inside running local function `f`
This is a global Lua function named 'bytecode'.
It has 1 fixed parameter.

Calling `upvaldemo(2)` from inside running local function `f`
This is a local Lua function named 'f'.
It has 1 fixed parameter and '...'.
local not_an_upvalue
local global = "global"

upvaldemo = function (f)
   local info = debug.getinfo(f)
   if info.name then
      if info.namewhat=='field' then print 
         (("This is a %s function named '%s' in some table."):
         format(info.what,info.name))
      else print (("This is a %s %s function named '%s'."):
         format(info.namewhat,info.what,info.name))
      end
   else print (("This is an anonymous %s function."):format(info.what))
   end
   local vararg=""
   if info.isvararg then vararg = " and '...'" end
   print (("It has %d fixed parameter%s%s."):format(info.nparams,
      info.nparams==1 and "" or "s",vararg))
   for n=1,200 do
      local yes,x = pcall(debug.upvalueid,f,n)
      if not yes then break end
      local name,val = debug.getupvalue(f,n)
      print(("Upvalue #%d at %s is named %s and has value '%s'"):
        format(n,tostring(x):match("(0x.*)"),name,val))
   end
end

bytecode = load(string.dump(upvaldemo))      
   
do          
   local a,b,c = 1,2,3
   print"\nCalling `upvaldemo(upvaldemo)`"
   upvaldemo(upvaldemo)
   print"\nCalling `upvaldemo(bytecode)"
   upvaldemo(bytecode)
   print"\nCalling `upvaldemo(pairs)`"
   upvaldemo(pairs)
   local function f(b,...)
      local t={a,b,c}
      print"\nCalling `upvaldemo(0)` from inside running local function `f`"
      upvaldemo(0)
      print"\nCalling `upvaldemo(1)` from inside running local function `f`"
      upvaldemo(1)
      print"\nCalling `bytecode(1)` from inside running local function `f`"
      bytecode(1)
      print"\nCalling `upvaldemo(2)` from inside running local function `f`"
      upvaldemo(2)
   end
   print"\nCalling `upvaldemo(f)` for a local function"
   upvaldemo(f)
   f(a,b,c)
end