[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: local "module" pattern without module [was Re: [ANN] SLAXML - pure Lua, robust-ish, SAX-like streaming XML processor]
- From: Petite Abeille <petite.abeille@...>
- Date: Mon, 18 Feb 2013 20:58:08 +0100
On Feb 18, 2013, at 3:43 PM, Gavin Kistner <phrogz@me.com> wrote:
> This works fine for this project where I only have two files. How would others suggest enforcing the same pattern for a different project that has many files all augmenting the same table?
Perhaps you are over thinking it? :)
Keep in mind the fundamentals: a module is just a table. Nothing more, nothing less.
As soon as one finds a reference to a module table, one is free to manipulate it any way one sees fit.
This can be as simple as:
do
local _ENV = require( 'mymodule' ) -- assuming 'mymodule' is defined somehow
function bar() end -- add a new function to mymodule
end
Of course, one could do the reverse and define multiple modules in one file, for example:
do
local _ENV = {}
function foo() end
package.loaded[ 'foo' ] = _ENV
end
do
local _ENV = {}
function bar() end
package.loaded[ 'bar' ] = _ENV
end
do
local _ENV = {}
function baz() end
package.loaded[ 'baz' ] = _ENV
end
Avoiding a 'return' in the module definition is rather handy as it allows one to combine multiple modules in one physical file, be it Lua code or bytecode, while coding or while deploying, or any combination thereof.
As an added bonus, defining modules in terms of _ENV enforces locality.
As this is/was a rather common pattern in 5.1, courtesy of the now deprecated 'module' function, one can of course reimplement it in 5.2 as well:
local function module( aName, ... )
local aModule = package.loaded[ assert( aName ) ]
if type( aModule ) ~= 'table' then
aModule = {}
aModule._M = aModule
aModule._NAME = aName
aModule._PACKAGE = aName:sub( 1, aName:len() - ( aName:reverse():find( '.', 1, true ) or 0 ) )
package.loaded[ aName ] = aModule
for anIndex = 1, select( '#', ... ) do
select( anIndex, ... )( aModule )
end
end
return aModule
end
Then one can define modules in 5.2 with all the convenience and features of 5.1, and then some:
local _ENV = module( 'dwim' )
…
FWIW, here is an example of the above principles at work:
http://alt.textdrive.com/svn/altdev/Mail/DB.lua
But sadly, now, in 5.2, every Tom, Dick, and Harry has to reimplement and reinvent their own half-baked way to handle module definitions. A sad step back from 5.1 where 'module' naturally, meaningfully, and predictably, complemented 'require'. Oh well, every one is entitled to their own mistakes. Even Lua's authors.