lua-users home
lua-l archive

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


On Sat, Aug 7, 2010 at 08:01, Petite Abeille <petite_abeille@mac.com> wrote:
>
> On Aug 7, 2010, at 12:47 AM, Javier Guerra Giraldez wrote:
>
>> my 2 centavos (S/.):
>
> And I raise you with my 2 centimes :)
>
>>
>> the require() function hasn't changed (AFAIK), so there's no
>> difference for users of libraries.  that also means that what a
>> library must provide to its users hasn't changed either.   if your
>> libraries did advanced package managing, you can still do the same; so
>> i don't think it's a 'real' loss of functionality, just (maybe) a loss
>> of convenience
>
> True, but now I will need to re-implement it by myself instead of using a standard, well defined module function.
>
>> for 'advanced' packages, you can always replicate what module() did.
>> it's not difficult;
>
> Sure, one can write its own [1], for example:
>
> local debug = require( 'debug' )
>
> local function UpValues( aFunction )
>    local anIndex = 0
>
>    return function()
>        anIndex = anIndex + 1
>        local aName, aValue = debug.getupvalue( aFunction, anIndex )
>
>        if aName then
>            return anIndex, aName, aValue
>        end
>    end
> end
>
> local function GetEnvironment( aFunction )
>    local aFunction = ( type( aFunction ) == 'function' and aFunction or debug.getinfo( aFunction + 1, 'f' ).func )
>
>    for anIndex, aName, aValue in UpValues( aFunction ) do
>        if aName == '_ENV' then
>            return aValue
>        end
>    end
> end
>
> local function SetEnvironment( aFunction, anEnvironment )
>    local aFunction = ( type( aFunction ) == 'function' and aFunction or debug.getinfo( aFunction + 1, 'f' ).func )
>
>    for anIndex, aName, aValue in UpValues( aFunction ) do
>        if aName == '_ENV' then
>            return debug.upvaluejoin( aFunction, anIndex, function() return anEnvironment end, 1 )
>        end
>    end
> end
>
> local function Module( aName )
>    local aModule = package.loaded[ aName ] or { }
>
>    aModule[ '_M' ] = aModule
>    aModule[ '_NAME' ] = aName
>
>    package.loaded[ aName ] = aModule
>
>    SetEnvironment( 2, aModule )
> end
>
> local print = print
> local require = require
>
> Module( 'DWIM' )
>
> function dwim()
>    print( 'dwim', _M, _NAME )
> end
>
>
> dwim()
>
> print( GetEnvironment( dwim ) )
>
> print( require( 'DWIM' ).dwim )
>
>
> Module( 'DWIM2' )
>
> function dwim()
>    print( 'dwim', _M, _NAME )
> end
>
>
> dwim()
>
> print( GetEnvironment( dwim ) )
>
> print( require( 'DWIM2' ).dwim )
>
>
> % lua -v TestModule.lua
> Lua 5.2.0 (work4)  Copyright (C) 1994-2010 Lua.org, PUC-Rio
> dwim    table: 0x100106d10      DWIM
> table: 0x100106d10
> function: 0x100106ff0
> dwim    table: 0x100107290      DWIM2
> table: 0x100107290
> function: 0x100107460
>
> But, as Everett mentioned somewhere else in this thread [2], this will lead to chaos as everybody and their dog will, one way or another, re-implement such functionality, in slightly incompatible ways :/
>
> Oh, well...
>
> [1] http://lua-users.org/lists/lua-l/2010-06/msg00313.html
> [2] http://lua-users.org/lists/lua-l/2010-08/msg00143.html
>
>
>
>
>

I've always just been using the return method:
local M = {}
function M.foo [...] end
function M.bar [...] end
return M
and then simply loading this file with require() (or a wrapper if I
need to load from a different directory).
myModule = require('moduleM')

Two modules in one file would be a simple matter of:
local M, N = {}, {}
...
return M, N
...
myModule, myOtherModule = require('moduleM')

Dividing one module into multiple files means either using
dofile/require in the main file to include others, or loading
individual sub-modules the same as you would normal ones, i.e.
myModule = require('moduleM')
myModule.moreStuff = require('moduleM-ext') --any naming convention you like

Maybe I'm naive but I've never quite understood the purpose of
module() when existing table functions and dofile/require seem to
fulfil this purpose just fine. The most "difficult" thing I've had to
do is extract my script's path from the global 'arg' and write a
dofile() wrapper that tries that if it can't load from the current
directory; a total of around 5 lines of code.

-- 
Sent from my toaster.