[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Lua 5.2.0 (work4) now available
- From: David Manura <dm.lua@...>
- Date: Tue, 3 Aug 2010 01:43:06 -0400
On Mon, Aug 2, 2010 at 12:55 PM, Jerome Vuarand
<jerome.vuarand@gmail.com> wrote:
> [code approximately as follows]
> local _M = {}; local _ENV = setmetatable({},{__index=_ENV, __newindex=_M}); function foo() _M.bar() end; function bar() print'!' end; return _M
I haven't found it advantageous to merge the _G table and a module's
public table into the same top-level global namespace because Lua
doesn't perfectly support the concept of there being *two*
simultaneous environment tables (e.g. _ENV1 and _ENV2 [1] or
package.clean [2]). Lua does, however, support one environment table
sharing the top-level namespace with local variables, which leads to
some variant of these four approaches:
local M = {}; function M.foo() M.bar() end; function M.bar()
print'!' end; return M
local function bar() print '!' end; local function foo() bar() end;
return {foo=foo, bar=bar}
local _G = _ENV; _ENV={}; function foo() bar() end; function bar()
_G.print'!' end; return _ENV
local print=print; _ENV={}; function foo() bar() end; function bar()
print'!' end; return _ENV
IMO, the these are fine semantically, with the first one being the
simplest and the second being the most efficient. However, if you'd
like, you could devise ways for Lua to shorten them. For example, let
`require` build a private environment {__index = _G, M = {}}, to avoid
the `local M = {}; ..... return M` boilerplate or make _M be a macro
that auto-expands to a table of all local functions except "private"
functions prefixed by '_'.
But here's another, IMO practical, idea along the lines of supporting
"two simultaneous environment tables":
_ENVW, = {}
_ENV = _G -- this line actually can be omitted but is included for clarity
function foo() bar() end
function bar() print'!' end
return _ENVW -- Note: rename _ENVW to something friendlier like
_PUBLIC if you want
What this would mean is that any global variable ever written to
within the current lexical scope (i.e. foo and bar) would be resolved
to the _ENVW table for both reads and writes, and all other global
variables that are only read from would be resolved to _ENV. So, the
above becomes bytecode-equivalent to
local _ENVW = {}
local _ENV = _G -- this line actually can be omitted but is
included for clarity
function _ENVW.foo() _ENVW.bar() end
function _ENVW.bar() _ENV.print'!' end
return _ENVW
and also has basically the same bytecode as my current preferred method:
local M = {}; function M.foo() M.bar() end; function M.bar()
print'!' end; return M
[1] http://lua-users.org/lists/lua-l/2010-07/msg00262.html
[2] http://lua-users.org/wiki/ModuleDefinition
- References:
- Re: [ANN] Lua 5.2.0 (work4) now available, Roberto Ierusalimschy
- Re: [ANN] Lua 5.2.0 (work4) now available, Florian Weimer
- Re: [ANN] Lua 5.2.0 (work4) now available, Luiz Henrique de Figueiredo
- Re: [ANN] Lua 5.2.0 (work4) now available, phlnc8
- Re: [ANN] Lua 5.2.0 (work4) now available, Jim Whitehead II
- Re: [ANN] Lua 5.2.0 (work4) now available, phlnc8
- Re: [ANN] Lua 5.2.0 (work4) now available, Quae Quack
- Re: [ANN] Lua 5.2.0 (work4) now available, GrayFace
- Re: [ANN] Lua 5.2.0 (work4) now available, James Graves
- Re: [ANN] Lua 5.2.0 (work4) now available, Jerome Vuarand