[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Basic, no fuss, no magic, foolproof module pattern. [Was: require, module, globals and "magic"]
- From: Sean Conner <sean@...>
- Date: Tue, 17 Aug 2010 17:18:09 -0400
It was thus said that the Great Lorenzo Donati once stated:
>
> I realized the discussion on the originating thread was hitting the
> limits of my Lua knowledge, so I'm starting a new thread to avoid adding
> noise to it with "newbie stuff".
>
> All the discussions about environments, globals and modules have
> confused me a bit (especially after rereading what's in the WIKI about it).
> Therefore I'd like to receive comments on my current practice when it
> comes to write a new module (nothing original below, just a concoction
> of what I read and learned about modules from the list and WIKI in the
> last months).
The problem (as I see it) comes down to poluting the global namespace.
module() basically loads some code and returns it in a new global table
(plus maybe some magic). I know that when I first started playing around
with Lua modules it wasn't all that intuitive to me.
Just in the past few days I came up with the following bit of code:
-- **********************************************************************
nmodules = {}
nmodules.lpath = { "./?.lua" }
nmodules.cache = {}
-- **********************************************************************
function loadtoenv(fname)
local env = setmetatable({} , { __index = _G } )
local f,err = loadfile(fname)
if f == nil then
return nil,nil,err
end
setfenv(f,env)
return f,env
end
-- ***********************************************************************
function nmodule(modname)
if nmodules.cache[modname] then
return nmodules.cache[modname]
end
for i = 1 , #nmodules.lpath do
local fname = string.gsub(nmodules.lpath[i],"%?",modname)
local f,env,err = loadtoenv(fname)
if f ~= nil then
nmodules.cache[modname] = env
env._NAME = modname
f()
return env
end
end
return nil,"module doesn't exist"
end
-- ***********************************************************************
A module then becomes just a Lua file with no other decorations. Say, a
small utility class:
-- ****[util.lua]*************
function split(s,delim)
local results = {}
local delim = delim or "%:"
local pattern = "([^" .. delim .. "]+)" .. delim .. "?"
for segment in string.gmatch(s,pattern) do
table.insert(results,segment)
end
return results
end
function access(name,mode)
local file = io.open(filename,mode)
if file then
file:close()
return true
else
return false
end
end
-- ****[end of line]**************
You can then include it with:
silly = nmodule('util')
path = silly.split(os.getenv("PATH"))
if not silly.access('/etc/passwd',"r") then
print("not on a unix system")
end
It wasn't hard to convert the one "module"ized project I have to use this
and it removed a bunch of lines of code (module(), local defs, etc). Any
"globals" in the individual Lua files included via nmodule() become table
members, and it's up to the caller to determine the name under which the
file is located.
I don't see why a new method like this can't be accepted, along with the
older method.
-spc
- Prev by Date:
Re: Idea for 5.2 : merging _ENV and ... (was: Re: reinstating "in env do ... end")
- Next by Date:
Re: Idea for 5.2 : merging _ENV and ... (was: Re: reinstating "in env do ... end")
- Previous by thread:
Re: Basic, no fuss, no magic, foolproof module pattern. [Was: require, module, globals and "magic"]
- Next by thread:
Re: Basic, no fuss, no magic, foolproof module pattern. [Was: require, module, globals and "magic"]
- Index(es):