lua-users home
lua-l archive

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


on 9/17/04 9:49 AM, Roberto Ierusalimschy at roberto@inf.puc-rio.br wrote:

> -- new module function
> --
> function _G.module (name)
> local ns = getfield(_G, name)         -- search for namespace
> if not ns then
>   ns = {}                             -- create new namespace
>   setmetatable(ns, {__index = _G})
>   setfield(_G, name, ns)
>   ns._NAME = name
>   ns._PACK = string.gsub(name, "[^.]*$", "")
> end
> package.loaded[name] = ns
> setfenv(2, ns)
> end

Further review and questions.

Does one really want the exported namespace for a module to inherit the
globals? Would one be better off with something like:

    function _G.module( name )
        local ns = getfield( _G, name )
        if not ns then
            ns = {}
            setfield( _G, name, ns )
        end
        package.loaded[ name ] = ns
        local env = setmetatable( {
            _NAME = name,
            _PACK = string.gsub(name, "[^.]*$", ""),
            _PUBLIC = ns
        }, {
            __index = function( t, k )
                return ns[ k ] or _G[ k ]
            end,
            __newindex = ns
        } )
    end

I added _PUBLIC to support the convention of declaring all of the functions
in a module as local functions to make intra-module calls avoid the table
lookup. _PUBLIC saves one the trouble of inventing new names since one can
just add a section to the module with:

    _PUBLIC.foo = foo

I guess that could also be handled by writing:

    function foo( ) ... end

    local foo = foo

More closely paralleling our own homebrew system, the module environment
could provide an export function that would take a table and add it's
entries to the namespace.

If one wants to live with slower lookups, I could see it being interesting
to have the option of creating the namespaces as write-protected outside the
module by exporting the following in place of ns:

    setmetatable( {}, {
        __index = ns,
        __newindex = function() error "write-protected" end,
        __metatable = "no peeking!"
    }

Mark