lua-users home
lua-l archive

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


2008/6/23 Gavin Kistner <gavin@phrogz.net>:
> I wanted to split foo.lua into a lot of manageable files, with foo.lua
> loading them. So I added this:
>
>  for _,fileName in pairs( subfiles ) do
>    -- yes, I added loadfile and setfenv as local variables
>    local fileChunk = loadfile( fileName )
>    setfenv( fileChunk, _M )
>    fileChunk( )
>  end
>
> While setfenv lets me call jim() from my sub file code, it does not give me
> access to bar, or any other local variables I set up prior to opening the
> module.
>
> What's the best way to accomplish this? I'd prefer to minimize the overhead
> of setup in all the subfiles to...well, ideally to zero. I'd like to just
> copy/paste code from foo.lua into them, add the subfilename to the list, and
> have it just work.

You can either use a wrapper environment between your subfiles and your module :

local subenv = setmetatable({ bar = bar }, {__index=_M, __newindex=_M})
for _,fileName in pairs( subfiles ) do
  -- yes, I added loadfile and setfenv as local variables
  local fileChunk = loadfile( fileName )
  setfenv( fileChunk, subenv )
  fileChunk( )
end

Or you can simply add some code automatically at the beginning of each subfile :

local header = [[
local bar = require 'bar'
]]
for _,fileName in pairs( subfiles ) do
  local source = io.open(filename):read"*a"
  local fileChunk = loadstring( header .. source )
  setfenv( fileChunk, _M )
  fileChunk( )
end

Both solution need zero adjustment to subfiles. The first one exposes
bar as a global, the second as a local. The second is slightly faster
but maybe less flexible.