[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Lua 5.2.0 (work4) now available
- From: Quae Quack <quae@...>
- Date: Tue, 3 Aug 2010 18:01:07 +1000
On 3 August 2010 15:43, David Manura <dm.lua@math2.org> wrote:
> 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
>
Can this not be done like so?:
local MOD = {}
local _ENV = setmetatable({},{__index=function(t,k) return MOD[k] or
_G[K] end , __newindex=function(t,k,v) MOD[k] = v end })
return MOD
- 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
- Re: [ANN] Lua 5.2.0 (work4) now available, David Manura