[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Lua 5.2.0 (work4) now available
- From: HyperHacker <hyperhacker@...>
- Date: Sat, 7 Aug 2010 08:36:10 -0600
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.