lua-users home
lua-l archive

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


2009/9/15 David Manura <dm.lua@math2.org>:
> I'm surprised I haven't thought of this sooner (nor seen this posted
> elsewhere).  Here are two "module" function options that in a simple
> way avoid the problem of a module's private namespace being polluted
> to its public namespace.
>
>  function package.clean(module)
>    local privenv = {_PACKAGE_CLEAN = true}
>    setfenv(3, setmetatable(privenv, {__index=_G,
> __newindex=function(_,k,v) rawset(privenv,k,v); module[k]=v end}))
>  end
>  function package.veryclean(module)
>    local privenv = {M=module, _PACKAGE_VERYCLEAN = true}
>    setfenv(3, setmetatable(privenv, {__index=_G}))
>  end

Nice trick, I'll keep this one handy, though I must say I've never
really been bothered by mymodule.print (except it being bad in a
sandbox).

> Still, my other complaints about the module function [2] still hold.
> Mainly, the module function writes the module's external API to the
> shared global environment (via the "luaL_findtable(L,
> LUA_GLOBALSINDEX, modname, 1)" call in loadlib.c:ll_module) rather
> than to the individual private namespaces of its clients.

Now *this* problem is quite easily the most annoying thing about the
module system, and Lua as a whole in fact. In a sandbox it causes
modules to load outside the current environment, and hence
inaccessible. module() is fairly easy to override in Lua, however
luaL_register() in the C API is not.

I think the solution is to shift the responsibility of setting
_G[modulename] to require(), rather than the modules. Then we are free
to re-implement require(), or add import(), or anything we would
rather, and existing scripts would be minimally affected. But right
now this is practically impossible to do without modifying the Lua
core.

I don't think I've heard much about changes to the package system in
5.2, I think I'd be being too hopeful if this was actually fixed for
that :)

Matthew