lua-users home
lua-l archive

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


Theodor-Iulian Ciobanu wrote:
> I could use a few pointers concerning the following:
> 
> 1) How to obtain the name of a pre-compiled running script?
> My first thought was debug.getinfo(1,'S').source, but it returns nil.
> 
> 2)  How  can  I  make  a  script  auto-load  itself  (when  
> it notices differences  between  itself  and  the  one  on  
> disk, for example)? I was thinking of doing something like this:
> 
> local modtime=lfs.attributes(fname,'modification')
> local fname=debug.getinfo(1,'S').source
> if (lfs.attributes(fname,'modification')~=modtime) then
>   return dofile(fname)
> end
> 
> But  I doubt this solution is stack friendly. This check 
> would be part of an almost infinite loop that would look like this:
> 
> repeat
>   BeUseful()
>   Sleep()
>   Update() -- this would be the previous code until (noloop)
> 
> Any idea will be appreciated.

The following primarily concerns your question 2. You can use the Lua
tail call mechanism to avoiding increasing the stack size no matter the
reload count. It implies that you load and run the script in two
seperate steps instead of calling dofile. There may be other
requirements that hasn't come to my mind yet.

Your current stack looks like:

script*
dofile
script*
dofile
script*
dofile
script*
dofile
script

The stack levels marked with a * can be reused through tail call. If you
change your code to something like:

local modtime=lfs.attributes(fname,'modification')
local fname=debug.getinfo(1,'S').source
if (lfs.attributes(fname,'modification')~=modtime) then
  local chunk = assert(loadfile(fname))
  return chunk()
end

The new stack looks like:

script*
script*
script*
script*
script

It could be nice that dofile is changed to make the loaded chunk reuse
its stack frame. You can use the implementation below to avoid modifying
your scripts (which also add the possibility to pass parameters to the
chunk):

function dofile(file, ...)
	local chunk = assert(loadfile(file))
	return chunk(...)
end

In the following (tested) recursive example, the virtual stack size use
would be 100k function calls:
-- test.lua ---------------------------------
local arg = {...}

local step = arg[1] or 1
print(step)

function dofile(file, ...)
	local chunk = assert(loadfile(file))
	return chunk(...)
end

if step > 100000 then
	return "foo"
else
	return dofile("test.lua", step+1)
end
---------------------------------------------