lua-users home
lua-l archive

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


thank you, nice explanation


2013/12/7 Philipp Janda <siffiejoe@gmx.net>
Am 07.12.2013 16:49 schröbte Peter Cawley:


The inner _ENV is an upvalue of func and subItem.func, and crucially
is a shared upvalue: the first upvalue of func is inner _ENV, and the
first upvalue of subItem.func is inner _ENV.

... and you can confirm that `item.func`, `item.subItem.func`, and `component` share the same upvalue by

    print( debug.upvalueid( item.func, 1 ) )
    print( debug.upvalueid( item.subItem.func, 1 ) )
    print( debug.upvalueid( component, 1 ) )



As such,
debug.setupvalue(item.func, 1, x) and
debug.setupvalue(item.subItem.func, 1, x) have the same effect.

If you want to change the upvalue reference of one function without affecting the others you can use `debug.upvaluejoin`:

    debug.setupvalue( item.func, 1, env1 )
    local function dummy() return env2 end
    debug.upvaluejoin( item.subItem.func, 1, dummy, 1 )
    -- now env2 in dummy and _ENV in subItem.func refer to the same upvalue
    print( debug.upvalueid( dummy, 1 ) )
    print( debug.upvalueid( item.subItem.func, 1 ) )

    -- an now those two functions use different _ENVs:
    item.func()
    item.subItem.func()


Philipp




On Sat, Dec 7, 2013 at 3:39 PM, Bruno Deligny <bruno.deligny@gmail.com> wrote:
Hi

I was playing with environements and i dont understand this behavior.

local env1 = {print=print, a=1}
local env2 = {print=print, a=2}

local component = load([[
   item = {
     func = function()
       print(a)
     end,
     subItem = {
       func = function()
         print(a)
       end,
     }
   }
   ]])

component()

debug.setupvalue(item.func, 1, env1)
debug.setupvalue(item.subItem.func, 1, env2)

item.func()
item.subItem.func()

This print:
2
2

I was hoping it printed:
1
2

It would be great if someone could explain to me how env is propagated.

Thanks