lua-users home
lua-l archive

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


It was thus said that the Great Egor Skriptunoff once stated:
> On Sun, Oct 25, 2015 at 8:29 PM, Patrick Donnelly <batrick@batbytes.com>
> wrote:
> 
> > The existing functionality (debug.upvaluejoin) is all you need to do
> > what you want:
> >
> > - Declare locals to be exported:
> >
> > local x = 1
> > export("x", function() return x end) -- **
> > local y = 2
> > export("y", function() return y end)
> >
> > - hook the load function which creates locals with the names of the
> > exported locals and then joins them to the loaded chunk, something
> > like:
> >
> 
> Patrick, thanks for the idea!
> It is quite workable, albeit rather anti-aesthetic due to exporting new
> function body for every local:
>   local a, b, c = 1, 2, 3
>   export("x", function() return a end)
>   export("y", function() return b end)
>   export("z", function() return c end)
>   local f = load_with_upvalues("print(x + y + z); x, y, z = x+1, y*2, z^3")
> Compare with this nice-and-easy thing I wanted:
>   local a, b, c = 1, 2, 3
>   local f = load_with_upvalues(@a, @b, @c, "upvalue x, y, z; print(x + y +
> z); x, y, z = x+1, y*2, z^3")

  One thing to keep in mind---chunks are functions.  So the following does
work:

	CODE1 = [[ 
	  local x = select(1,...) 
	  local y = select(2,...)
	  local z = select(3,...)
	  
	  return function() return x,y,z end   
	]]  
	
	f1 = load(CODE1,"code1","t",{select = select})("one",2,true)
	print(f1())

  This works to get external values into the locals of a chunk, but it
doesn't solve the issue of sharing upvalues among different chunks.  I have
noticed that despite this:

	Upvalues have no particular order, as they are active through the
	whole function. They are numbered in an arbitrary order.

that upvalues are numbered in a consistent order---the order they are
defined in (whether you can depend on this is another matter, but I've found
this to be true for Lua 5.2 and Lua 5.3), so this also works:

	CODE1 = [[ local x,y; return function() return x,y end ]]
	CODE2 = [[ local x,y; return function() return x,y end ]]

	f1 = load(CODE1,"code1","t",{})()
	f2 = load(CODE2,"code2","t",{})()

	debug.upvaluejoin(f1,1,f2,1)
	debug.upvaluejoin(f1,2,f2,2)

	debug.setupvalue(f1,1,14)
	debug.setupvalue(f2,2,"hello")

	print(f1())
	print(f2())
	print()

as does this:

	function load_with_upvalues(code,join,...)               
	  local f = load(code)()               
	
	  if join then
	    local info = debug.getinfo(join)
	    for i = 1 , info.nups do
	      debug.upvaluejoin(f,i,join,i)
	    end
	  else 
	    for i = 1 , select('#',...) do
	      local v = select(i,...)
	      debug.setupvalue(f,i,v)
	    end
	  end  
	       
	  return f
	end
   
	CODE1 = [[ local x,y; return function() return x,y end ]]
	CODE2 = [[ local x,y; return function() return x,y end ]]

	f1 = load_with_upvalues(CODE1,false,14,"hello")               
	f2 = load_with_upvalues(CODE2,f1)               
	
	print(f1())
	print(f2())
	print()

  -spc